生成具有绑定值的整个 SQL 语句以用作缓存函数的键 - CakePHP 4
Generate whole SQL statement with binding value to use as a key for cache function - CakePHP 4
问题描述
我想将查询结果缓存为整个 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')));
});
以上示例取自 link:https://book.cakephp.org/4/en/orm/query-builder.html#caching-loaded-results
我试过的
我可以获得完整的 SQL 没有像这样的绑定值:
$query->sql()
绑定值如下:
$bindings = $query->getValueBinder()->bindings();
现在我需要弄清楚如何将两者结合起来。最好是 CakePHP 中有一个内置函数,它只会给我 SQL 和绑定值。
我找到了解决方法。 DebugKit 中有一个名为 interpolate() 的私有函数,它使用绑定值创建完整的 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 = [
'$' => '\$',
'\' => '\\\\',
"'" => "''",
];
$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 语句:
$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 语句的一部分,如下例所示:
// Generate a key based on a simple checksum
// of the query's where clause
$query->cache(function ($q) {
return md5(serialize($q->clause('where')));
});
以上示例取自 link:https://book.cakephp.org/4/en/orm/query-builder.html#caching-loaded-results
我试过的
我可以获得完整的 SQL 没有像这样的绑定值:
$query->sql()
绑定值如下:
$bindings = $query->getValueBinder()->bindings();
现在我需要弄清楚如何将两者结合起来。最好是 CakePHP 中有一个内置函数,它只会给我 SQL 和绑定值。
我找到了解决方法。 DebugKit 中有一个名为 interpolate() 的私有函数,它使用绑定值创建完整的 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 = [
'$' => '\$',
'\' => '\\\\',
"'" => "''",
];
$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 语句:
$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);