Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 有没有办法在Phalcon中使用新的PostgreSQL 9.3 JSON操作符?_Php_Phalcon_Postgresql 9.3 - Fatal编程技术网

Php 有没有办法在Phalcon中使用新的PostgreSQL 9.3 JSON操作符?

Php 有没有办法在Phalcon中使用新的PostgreSQL 9.3 JSON操作符?,php,phalcon,postgresql-9.3,Php,Phalcon,Postgresql 9.3,我正在寻找一种方法来利用新的技术 一个简单的表格来演示: CREATE TABLE "user" ( id_user serial NOT NULL, data json, CONSTRAINT pk_user PRIMARY KEY (id_user) ) 以及在psql中运行良好的查询: select * from "user" where data->>'email' = 'john@example.com'; 但是,当针对以下对象使用时: 它会产生语法错误:

我正在寻找一种方法来利用新的技术

一个简单的表格来演示:

CREATE TABLE "user"
(
  id_user serial NOT NULL,
  data json,
  CONSTRAINT pk_user PRIMARY KEY (id_user)
)
以及在
psql
中运行良好的查询:

select * from "user" where data->>'email' = 'john@example.com';
但是,当针对以下对象使用时:

它会产生语法错误:

ERROR: Syntax error, unexpected token >, near to '>'email' = :email:', when parsing: SELECT [Pht\Cli\Model\UserModel].* FROM [Pht\Cli\Model\UserModel] WHERE data->>'email' = :email:
我猜这和不能处理语法有关。但问题仍然存在:如何将JSON查询与Phalcon一起使用

我尝试将JSON语法包装成:

但它似乎只是为了更新/插入:

ERROR: Conditions must be string

我总是可以编写一个原始查询,但这显然不是正确的方法。另外,最好在
Model::find
Model::findAll
中提供语法,看看是否有一个底层函数实现了
->
操作符,并改用它。您可以在
->
oprname
中查找
pg\u操作符
;您将看到
oprcode
标识底层函数。对于不同的数据类型组合,可能有多个条目,因此您必须选择正确的条目。如果需要,您可以在
pg_type
上加入
oprift
opright
以获取类型名称


那会给你一个临时的解决办法。更好的方法是避免尝试在框架中解析SQL,或修复其解析器以处理复杂的运算符。

在深入研究源代码和阅读论坛后,我发现了一个基于SQL的非常好的解决方法。基本思想是使用自定义数据库函数语法,在执行查询之前捕获并解析一个特殊的虚拟函数:

UserModel::query()->where("PG_JSON_PATH(\"data->>'email'\") = :email:");
为了实现这一点,我们需要一个专门的Postgres适配器(下面的一个适配器也使用这种方法来潜入原始帖子中的子查询):


目前,您可以使用内置的postgres功能:


根据Craig answer,您可以在Postgres上执行此查询,以查找您要查找的操作员以及在查询中使用的等效代码: 例如:
从pg_运算符中选择oprcode,其中oprname='->'

你会得到很多结果,使用合适的方法


谢谢,

Phalcon是用C编写的,所有查询在内部都被翻译成一种叫做PHQL的特殊语言,PHQL本身就是用lemon实现的。我翻遍了源代码,没有迹象表明qurrent PHQL实现可以支持
->
符号。当我有空余时间时,我会尽力的。
ERROR: Conditions must be string
UserModel::query()->where("PG_JSON_PATH(\"data->>'email'\") = :email:");
class Postgresql93 extends \Phalcon\Db\Adapter\Pdo\Postgresql
{
    public function query($sqlStatement, $bindParams = null, $bindTypes = null)
    {
        $sqlStatement = $this->handle93syntax($sqlStatement);
        return parent::query($sqlStatement, $bindParams, $bindTypes);
    }

    private function handle93syntax($sqlStatement)
    {
        $specials = join('|', ['SUB_QUERY', 'PG_JSON_PATH']);
        $pattern = "/($specials)[\\s]*\\([\\s]*\\'(.*)\\'[\\s]*\\)/";

        $sqlStatement = preg_replace_callback(
            $pattern,
            function(array $matches){
                $content = str_replace("''", "'", $matches[2]);
                return $content;
            },
            $sqlStatement
        );

        return $sqlStatement;
    }
}
UserModel::query()->where("json_extract_path_text(data, 'email') = :email:");