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

时间:2018-09-13 03:46:41

标签: php doctrine-orm doctrine doctrine-query

注意:这不是What is maximum query size for 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 DriverException SQLSTATE[HY093]: Invalid parameter number: no parameters were bound。确实,从错误输出中可以看出,Doctrine没有尝试输入我告诉它的参数。

经过数小时的调试,我终于弄清楚这与查询本身的 length 有关。如果查询字符串少于3,074个字符,它将很好地运行。此外,仅对于准备好的语句会出现此问题。如果我不需要绑定任何参数,那么真正长的查询(超过3074个字符)可以很好地工作。

为了使问题更加困惑,我只在本地环境(PHP 7.2)上收到此错误,而在PHP 5.6上仍未得到生产。我不知道PHP是否是问题所在,但我想不出其他任何原因。我已经运行composer update以获得PHP 7.2的最新版本的依赖项(Doctrine等)。

我不认为这是由于MySQL max_allowed_packet选项或MySQL中其他值太低所致,因为我可以在MySQL控制台中手动运行查询(输入参数值),并且作品。因此,我只能责怪Doctrine或PHP本身。

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

1 个答案:

答案 0 :(得分:1)

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

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

$sql = 'SELECT COUNT(*) FROM post WHERE username = :username AND comment REGEXP :comment_regex;';

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

旁注:为了提高性能和实用性,我建议使用ID而不是用户名作为外键,以提高性能和实用性。