如何使用 CakePHP3 ORM 获取字符串格式的 where 子句?
Posted
技术标签:
【中文标题】如何使用 CakePHP3 ORM 获取字符串格式的 where 子句?【英文标题】:how to get the where clause in string format using CakePHP3 ORM? 【发布时间】:2015-01-17 05:57:11 【问题描述】:在 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
。
【问题讨论】:
【参考方案1】:要直接回答您的问题,您可以通过这种方式获取任何子句的 SQL:
$binder = new \Cake\ORM\ValueBinder();
$query->clause('where')->sql($binder);
这将返回带有正确占位符的 SQL,而不是要使用的值。这些值位于$binder
变量中,用于语句对象。
如我所见,您只想保留 where
子句的内部结构,以便将其传递给不同请求中的另一个查询。您的解决方案很好,但我想补充一点,您还可以从现有查询中编码完整的条件树:
$where = serialize($query->clause('where'));
$anotherQuery->where(unserialize($where)); // A query in another request
在任何情况下,您都需要谨慎处理要反序列化的内容,因为直接从用户输入中获取肯定会导致安全问题。
【讨论】:
谢谢洛伦佐。这很有用。【参考方案2】:如果你愿意,你可以选择省略这个参数。请看http://api.cakephp.org/3.0/class-Cake.Database.Query.html#_sql
另外,可以使用Query的成员函数traverse($visitor, $parts)来隔离where子句。 $visitor 是一个接受值和子句的函数。您定义 $visitor 的行为。 $parts 是一个子句名称数组。我建议将 array('where') 传递给这个参数。
【讨论】:
您的回答没有帮助。它以字符串形式返回整个 SQL 查询 + 占位符仍然存在。换句话说,我会得到字符串SELECT Articles.* from Articles where Articles.id = c:0
好吧,你最后问到了ValueBinder。 ValueBinder 的唯一成员除了它的公共函数之外是受保护的。如果你只是想提取 where 子句,那么也许有更好的路线
好的,我已经改写了我的问题。最终,我只想以字符串格式获取正确 SQL 方言中的 where 子句。只是 where 子句而不是整个查询。还填写了值。
谢谢。我为我的情况找到了一种解决方法,它不像我最初认为的那样复杂。【参考方案3】:
我的解决方法是将条件存储为 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
这让我得到了我最终想要的东西。
【讨论】:
以上是关于如何使用 CakePHP3 ORM 获取字符串格式的 where 子句?的主要内容,如果未能解决你的问题,请参考以下文章
CakePHP 3.x ORM get()、find() 以及如何禁用befeoreFind()?
Cakephp3:如何在询问标记后使用get参数获取当前页面的完整URL