生成带有绑定值的完整 SQL 语句以用作缓存功能的键 - CakePHP 4

发布于 2025-01-10 17:01:13 字数 837 浏览 0 评论 0原文

问题描述

我想将带有键的查询结果缓存为整个 SQL 语句,而不是 SQL 语句的一部分,如下例所示:

// Generate a key based on a simple checksum
// of the query's where clause
$query->cache(function ($q) {
    return md5(serialize($q->clause('where')));
});

上面的示例取自此链接: https://book.cakephp.org/4/en/orm/query-builder.html#caching-loaded-results

我尝试过的

我可以获得完整的 SQL,而无需像这样的绑定值:

$query->sql()

绑定值是这样的:

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

现在我需要弄清楚如何将两者结合起来。如果 CakePHP 中有一个内置函数,它只会为我提供带有绑定值的 SQL,那就最好了。

Problem Description

I want to cache the query results with the key as a whole SQL statement instead part of the SQL statement like the below example:

// Generate a key based on a simple checksum
// of the query's where clause
$query->cache(function ($q) {
    return md5(serialize($q->clause('where')));
});

Above example taken from this link : https://book.cakephp.org/4/en/orm/query-builder.html#caching-loaded-results

What I have tried

I can get the full SQL without the binding value like this:

$query->sql()

And the binding values like this:

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

Now I need to figure out how to combine the both. It would be best if there is a built in function in CakePHP which would just give me the SQL with the binding value.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

戏剧牡丹亭 2025-01-17 17:01:13

我已经找到了解决这个问题的方法。 DebugKit 中有一个名为 interpolate()< 的私有函数/a> 使用绑定值创建完整的 SQL 语句。

由于该函数是私有的,您必须复制它并将其保存在源代码中。

这是插值函数:

    /**
     * Helper function used to replace query placeholders by the real
     * params used to execute the query.
     *
     * @param string $sql The SQL statement
     * @param array $bindings The Query bindings
     * @return string
     */
    private static function interpolate($sql, array $bindings)
    {
        $params = array_map(function ($binding) {
            $p = $binding['value'];

            if ($p === null) {
                return 'NULL';
            }
            if (is_bool($p)) {
                return $p ? '1' : '0';
            }

            if (is_string($p)) {
                $replacements = [
                    '

然后调用它并传递 SQL 和绑定值,如下所示,以获得带有绑定值的整个 SQL 语句:

$sql = $query->sql();
$bindings = $query->getValueBinder()->bindings();

// to make the example easier, I have saved the interpolate function in controller
$properSqlStatement = $this->interpolate($sql, $bindings);

=> '\\

然后调用它并传递 SQL 和绑定值,如下所示,以获得带有绑定值的整个 SQL 语句:


, '\\' => '\\\\\\\\', "'" => "''", ]; $p = strtr($p, $replacements); return "'$p'"; } return $p; }, $bindings); $keys = []; $limit = is_int(key($params)) ? 1 : -1; foreach ($params as $key => $param) { $keys[] = is_string($key) ? "/$key\b/" : '/[?]/'; } return preg_replace($keys, $params, $sql, $limit); } }

然后调用它并传递 SQL 和绑定值,如下所示,以获得带有绑定值的整个 SQL 语句:

I have found the solution to this. There is a private function in DebugKit named interpolate() which create the full SQL statement with the binding value.

As the function is private, you have to copy it and save it in your source code.

Here's the interpolate function :

    /**
     * Helper function used to replace query placeholders by the real
     * params used to execute the query.
     *
     * @param string $sql The SQL statement
     * @param array $bindings The Query bindings
     * @return string
     */
    private static function interpolate($sql, array $bindings)
    {
        $params = array_map(function ($binding) {
            $p = $binding['value'];

            if ($p === null) {
                return 'NULL';
            }
            if (is_bool($p)) {
                return $p ? '1' : '0';
            }

            if (is_string($p)) {
                $replacements = [
                    '

And then call it and pass the SQL and the binding values like this to get the whole SQL statement with the binding values:

$sql = $query->sql();
$bindings = $query->getValueBinder()->bindings();

// to make the example easier, I have saved the interpolate function in controller
$properSqlStatement = $this->interpolate($sql, $bindings);

???? Yay !

=> '\\

And then call it and pass the SQL and the binding values like this to get the whole SQL statement with the binding values:


???? Yay !

, '\\' => '\\\\\\\\', "'" => "''", ]; $p = strtr($p, $replacements); return "'$p'"; } return $p; }, $bindings); $keys = []; $limit = is_int(key($params)) ? 1 : -1; foreach ($params as $key => $param) { $keys[] = is_string($key) ? "/$key\b/" : '/[?]/'; } return preg_replace($keys, $params, $sql, $limit); } }

And then call it and pass the SQL and the binding values like this to get the whole SQL statement with the binding values:

???? Yay !

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文