【问题标题】:how to get the where clause in string format using CakePHP3 ORM?如何使用 CakePHP3 ORM 获取字符串格式的 where 子句?
【发布时间】: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

【问题讨论】:

    标签: php mysql cakephp orm cakephp-3.0


    【解决方案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
    

    这让我得到了我最终想要的东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-24
      • 1970-01-01
      • 2012-03-28
      • 1970-01-01
      • 2021-12-29
      • 2013-08-24
      • 1970-01-01
      • 2014-03-31
      相关资源
      最近更新 更多