CakePHP 3 - 查询对象的访问参数
CakePHP 3 - access params of Query object
在 CakePHP 中 3.x 我可以这样做:
$Substances = TableRegistry::get('Substances');
$query = $Substances->find()->where($where_conditions)->select(['id']);
debug($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
语句的值写入新的 table ( 重要提示: 请参阅 this link 了解其在原版 MySQL 中的工作原理示例。我无法弄清楚如何使用 Cake 中的 ORM 来做到这一点,所以正计划编写一个自定义函数。但是我需要能够访问 SQL 以及绑定的参数,以便可以在我自己的函数中执行查询。
如果您知道我可以使用 ORM 执行 CREATE TABLE AS
查询的解决方案,我仍然有兴趣了解这个。但是我想知道 params
是否也可以在 debug()
之外访问。
前提:我其实不明白你为什么需要参数
无论如何。您需要的信息由查询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();
CakePHP 不提供创建此类 CREATE TABLE AS
语句的具体方法,因此您必须自己构建它。
使用查询对象 sql()
方法编译问题中显示的查询非常简单,正如 arilia 已经提到的那样,您将能够访问绑定到该查询的参数 after 被编译。
有了编译的 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
...
另见
在 CakePHP 中 3.x 我可以这样做:
$Substances = TableRegistry::get('Substances');
$query = $Substances->find()->where($where_conditions)->select(['id']);
debug($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
语句的值写入新的 table ( 重要提示: 请参阅 this link 了解其在原版 MySQL 中的工作原理示例。我无法弄清楚如何使用 Cake 中的 ORM 来做到这一点,所以正计划编写一个自定义函数。但是我需要能够访问 SQL 以及绑定的参数,以便可以在我自己的函数中执行查询。
如果您知道我可以使用 ORM 执行 CREATE TABLE AS
查询的解决方案,我仍然有兴趣了解这个。但是我想知道 params
是否也可以在 debug()
之外访问。
前提:我其实不明白你为什么需要参数
无论如何。您需要的信息由查询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();
CakePHP 不提供创建此类 CREATE TABLE AS
语句的具体方法,因此您必须自己构建它。
使用查询对象 sql()
方法编译问题中显示的查询非常简单,正如 arilia 已经提到的那样,您将能够访问绑定到该查询的参数 after 被编译。
有了编译的 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
...
另见