如何使用 CakePHP3 ORM 获取字符串格式的 where 子句?
how to get the where clause in string format using CakePHP3 ORM?
在 CakePHP3 中,有一个 ORM 可以帮助构建查询。
从documentation可以看出
$query = $articles->find(); // build a query that has not run yet
$query->where(['id' => 1]); // Return the same query object
所以在这种情况下,我想要字符串
WHERE `articles`.`id` = 1
经过多次谷歌搜索,我发现有一种方法to return just the where clause of a query object。
$query->where(['id' => 1])->clause('where'); // Return the where clause in the form of a QueryExpression
更多的谷歌搜索让我找到了如何get the QueryExpression to spit out string representation
$query->where(['id' => 1])->clause('where')->sql($valueBinder); // Return the where clause in string format
这是我的问题。我不知道 $valueBinder 应该是什么样子。不知道怎么初始化。
我也很高兴不使用 ValueBinder,只要我可以使用 CakePHP 3 ORM 和正确的 SQL 方言获得字符串格式的 where 子句。请假设我使用的是 MySQL.
请指教
编辑
我尝试使用 $query->valueBinder()
作为 $valueBinder
。
它是空的,不包含关联的 c:0
到值 1
。
如果你愿意,你可以选择省略这个参数。请参阅 http://api.cakephp.org/3.0/class-Cake.Database.Query.html#_sql
另外,可以使用Query成员函数traverse($visitor, $parts)来隔离where子句。 $visitor 是一个带有值和子句的函数。您定义 $visitor 的行为。 $parts 是子句名称的数组。我建议将 array('where') 传递给这个参数。
我的解决方法是将条件存储为 json 字符串格式。
用同样的例子,我做的是
$data['conditions'] = json_encode(['Articles.id' => 1]); // encode into JSON string
$this->DynamicRules->patchEntity($dynamicRule, $data); // use in edit action of DynamicRulesController
然后当我需要重用条件时,我会这样做:
$articlesTable = TableRegistry::get('Articles');
$query = $articlesTable->find(); // new query for Articles
$rule = json_decode($dynamicRule->conditions, true); // get back the conditions in associative array format
$query->where($rule); // re-assign the conditions back
这让我得到了我最终想要的东西。
要直接回答您的问题,您可以通过以下方式获得任何子句的 SQL:
$binder = new \Cake\ORM\ValueBinder();
$query->clause('where')->sql($binder);
这将 return SQL 与正确的占位符,而不是要使用的值。这些值存在于 $binder
变量中并用于语句对象。
如我所见,您只想保留 where
子句的内部结构以将其传递给不同请求中的另一个查询。您的解决方案很好,但我想补充一点,您还可以根据现有查询对完整条件树进行编码:
$where = serialize($query->clause('where'));
$anotherQuery->where(unserialize($where)); // A query in another request
在任何情况下,您都需要小心反序列化的内容,因为直接从用户输入中获取它肯定会导致安全问题。
在 CakePHP3 中,有一个 ORM 可以帮助构建查询。
从documentation可以看出
$query = $articles->find(); // build a query that has not run yet
$query->where(['id' => 1]); // Return the same query object
所以在这种情况下,我想要字符串
WHERE `articles`.`id` = 1
经过多次谷歌搜索,我发现有一种方法to return just the where clause of a query object。
$query->where(['id' => 1])->clause('where'); // Return the where clause in the form of a QueryExpression
更多的谷歌搜索让我找到了如何get the QueryExpression to spit out string representation
$query->where(['id' => 1])->clause('where')->sql($valueBinder); // Return the where clause in string format
这是我的问题。我不知道 $valueBinder 应该是什么样子。不知道怎么初始化。
我也很高兴不使用 ValueBinder,只要我可以使用 CakePHP 3 ORM 和正确的 SQL 方言获得字符串格式的 where 子句。请假设我使用的是 MySQL.
请指教
编辑
我尝试使用 $query->valueBinder()
作为 $valueBinder
。
它是空的,不包含关联的 c:0
到值 1
。
如果你愿意,你可以选择省略这个参数。请参阅 http://api.cakephp.org/3.0/class-Cake.Database.Query.html#_sql
另外,可以使用Query成员函数traverse($visitor, $parts)来隔离where子句。 $visitor 是一个带有值和子句的函数。您定义 $visitor 的行为。 $parts 是子句名称的数组。我建议将 array('where') 传递给这个参数。
我的解决方法是将条件存储为 json 字符串格式。
用同样的例子,我做的是
$data['conditions'] = json_encode(['Articles.id' => 1]); // encode into JSON string
$this->DynamicRules->patchEntity($dynamicRule, $data); // use in edit action of DynamicRulesController
然后当我需要重用条件时,我会这样做:
$articlesTable = TableRegistry::get('Articles');
$query = $articlesTable->find(); // new query for Articles
$rule = json_decode($dynamicRule->conditions, true); // get back the conditions in associative array format
$query->where($rule); // re-assign the conditions back
这让我得到了我最终想要的东西。
要直接回答您的问题,您可以通过以下方式获得任何子句的 SQL:
$binder = new \Cake\ORM\ValueBinder();
$query->clause('where')->sql($binder);
这将 return SQL 与正确的占位符,而不是要使用的值。这些值存在于 $binder
变量中并用于语句对象。
如我所见,您只想保留 where
子句的内部结构以将其传递给不同请求中的另一个查询。您的解决方案很好,但我想补充一点,您还可以根据现有查询对完整条件树进行编码:
$where = serialize($query->clause('where'));
$anotherQuery->where(unserialize($where)); // A query in another request
在任何情况下,您都需要小心反序列化的内容,因为直接从用户输入中获取它肯定会导致安全问题。