CakePHP 3 - 访问Query对象的参数

时间:2018-03-26 10:17:34

标签: cakephp orm query-builder create-table cakephp-3.x

在CakePHP 3.x中,我可以这样做:

$Substances = TableRegistry::get('Substances');
$query = $Substances->find()->where($where_conditions)->select(['id']);
debug($query); 

这将显示Query对象。

如果我想获取SQL字符串,我可以使用debug($query->sql());。这将为我提供带有任何参数占位符的SQL字符串,例如

SELECT ... WHERE ... in (:c0,:c1,:c2))

使用debug($query)时,我可以看到:c0:c1等的值:

'params' => [
    ':c0' => [
        'value' => (int) 47,
        'type' => 'smallinteger',
        'placeholder' => 'c0'
    ],
    ':c1' => [
        'value' => (int) 93,
        'type' => 'smallinteger',
        'placeholder' => 'c1'
    ],
    ':c2' => [
        'value' => (int) 845,
        'type' => 'smallinteger',
        'placeholder' => 'c2'
    ],
    ':c3' => [
        'value' => (int) 354,
        'type' => 'smallinteger',
        'placeholder' => 'c3'
    ]
]

但是,我无法在debug声明之外访问它们。例如$query->params()$query['params']没有给我参数 - 它会出错。我希望能够将此数组传递给自定义函数,那么我该如何访问它呢?

这很奇怪,因为我可以使用debug($query->sql())来获取上面的SQL字符串,而params只是该对象中的另一个东西,但似乎无法访问。

我已阅读How to get params from query object in CakePHP 3,但认为这是一个不同的问题,因为由于debug提供的默认深度而没有看到debug语句中的值。

我想这样做的原因是因为我希望能够执行CREATE TABLE AS查询,将SELECT语句的值写入新表(重要:< / b>有关如何在vanilla MySQL中运行的示例,请参阅this link。我无法弄清楚如何使用Cake中的ORM来做到这一点,因此计划编写自定义函数。但我需要能够访问SQL以及绑定的参数,以便可以在我自己的函数中执行查询。

如果有人有任何提示/建议,将不胜感激。如果您知道我可以使用ORM执行CREATE TABLE AS查询的解决方案,我仍然有兴趣知道这一点。不过,我想知道params是否可以在debug()之外访问。

2 个答案:

答案 0 :(得分:2)

CakePHP没有提供创建此类CREATE TABLE AS语句的具体方法,因此您必须自己构建它。

使用查询对象sql()方法编译问题中显示的查询很简单,并且已经提到过arilia,您将能够访问绑定到该查询的参数 之后编译。

使用已编译的SQL和关联的值绑定器,您可以将其与自定义原始查询结合使用以构建CREATE TABLE AS语句。您需要做的就是使用已编译的SQL准备一个新语句,并通过自己的attachTo()方法附加值绑定器。

您可能还需要做的一件事是在select()中定义自定义别名,否则您最终会以Substances_id的形式选择(和创建)列

$Substances = TableRegistry::get('Substances');

$selectQuery = $Substances
    ->find()
    ->where($where_conditions)
    ->select(['id' => 'id']); // < create aliases as required

// compile the ORM query, this will populate the value binder
$selectSql = $selectQuery->sql();

// combine table creation SQL and compiled ORM query in a single statement
$createStatement = $Substances
    ->getConnection()
    ->prepare('CREATE TABLE dynamic_table AS ' . $selectSql);

// attach the ORM querys value binder, binding all its values to the given statement
$selectQuery->getValueBinder()->attachTo($createStatement);

$success = $createStatement->execute();

这应该创建类似于:

的SQL
CREATE TABLE dynamic_table AS 
    SELECT 
      id AS id
    FROM 
      substances Substances 
    WHERE 
      ...

另见

答案 1 :(得分:1)

前提:我实际上并不理解为什么你需要这个参数

反正。您需要的信息由查询ValueBinder对象

存储

所以你可以简单地做

$params = $query->getValueBinder()->bindings();
debug($params);

但由于某种原因,这会让你得到一个空数组。我的猜测是查询首先需要某种初始化。

实际上如果你运行

debug($query);
$params = $query->getValueBinder()->bindings();
debug($params);
你会看到你的参数。我认为比我更专业的人会来并给出一个完整的解释

编辑:我注意到调试$query调用了$query->sql()来调用conection->compileQuery();

所以你可以做到

$query->sql(); // you need this to compile the query
               // and generate the bindings
$params = $query->getValueBinder()->bindings();