具有绑定参数的大型查询会导致 Doctrine 中的参数编号错误无效



注意:这不是 mysql 的最大查询大小是多少?的副本。我的问题似乎是特定于Doctrine和/或PHP,而不是MySQL。

我的查询如下所示:

SELECT COUNT(*) FROM post
WHERE username = :username
AND comment REGEXP '...giant regular expression...'

请注意,巨大的正则表达式不包括文本:username(这可能会混淆教义(。

我的PHP是正常的Doctrine DQL,类似于

$connection->executeQuery($sql, ['username' => 'Frank Sinatra']);

我正在收到PDO驱动程序异常SQLSTATE[HY093]: Invalid parameter number: no parameters were bound。事实上,我从错误输出中可以看出,Doctrine并没有试图输入我告诉它的参数。

经过数小时的调试,我终于发现这与查询本身的长度有关。如果查询字符串少于大约 3,074 个字符,它将正常运行。此外,此问题仅发生在预准备语句中。如果我不需要绑定任何参数,则非常长(超过 3,074 个字符(的查询可以正常工作。

更令人困惑的是,我只在我的本地环境(PHP 7.2(上收到此错误,而不是仍在 PHP 5.6 上的生产环境。我不知道PHP是否是问题所在,但我想不出还有什么其他问题。我已经运行了composer update以获取 PHP 7.2 的最新版本的依赖项(Doctrine 等(。

我不认为这是由于 MySQLmax_allowed_packet选项的值较低,或者 MySQL 中的其他任何内容,因为我可以在 MySQL 控制台中手动运行查询(输入参数值(并且它可以工作。所以,我只能责怪Doctrine或PHP本身。

有人听说过这个问题吗?PHP或Doctrine中是否有一些关于最大查询长度的秘密设置,这会导致Doctrine以这种方式感到困惑?

正则表达式是什么样子的,你是如何生成的?它有问号吗?如果是这样,它将期望您为这些绑定参数。

如果您还没有,您也应该绑定正则表达式值:

$sql = 'SELECT COUNT(*) FROM post WHERE username = :username AND comment REGEXP :comment_regex;';
$connection->executeQuery($sql, [
'username'      => $username,
'comment_regex' => $comment_regex,
]);

旁注:为了性能和实用性,我建议使用ids而不是用户名作为外键(如果您必须更改用户名,那就不好玩了(。

相关内容

最新更新