Большой запрос со связанными параметрами вызывает ошибку неверного номера параметра в Doctrine - PullRequest
0 голосов
/ 13 сентября 2018

ПРИМЕЧАНИЕ. Это не дубликат Каков максимальный размер запроса для 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 не пыталась ввести параметры, о которых я говорила.

После нескольких часов отладки я наконец понял, что это как-то связано с длиной самого запроса. Если строка запроса содержит менее 3074 символов, она будет работать нормально. Кроме того, эта проблема возникает только для подготовленных заявлений. Очень длинный запрос (более 3074 символов) работает нормально, если мне не нужно привязывать какие-либо параметры.

Чтобы сделать это еще более непонятным, я получаю эту ошибку только в моей локальной среде (PHP 7.2), а не в производственной, которая все еще работает на PHP 5.6. Я не знаю, является ли проблема PHP, но я не могу думать ни о чем другом, что могло бы быть этим. Я запустил composer update, чтобы получить последнюю версию зависимостей (Doctrine и т. Д.) Для PHP 7.2.

Я не верю, что это связано с низким значением параметра MySQL max_allowed_packet или чего-либо еще в MySQL, потому что я могу запустить запрос вручную (введя значения параметров) в консоли MySQL, и он работает. Итак, я остаюсь виноват либо в Doctrine, либо в самом PHP.

Кто-нибудь слышал об этой проблеме? Есть ли какой-нибудь секретный параметр для максимальной длины запроса в PHP или Doctrine, который может привести к путанице в Doctrine?

1 Ответ

0 голосов
/ 13 сентября 2018

Как выглядит регулярное выражение и как вы его генерируете? Есть ли у него знак вопроса? Если это так, то ожидается, что вы свяжете параметры для них.

Если вы еще этого не сделали, вам также следует связать значение регулярного выражения:

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

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

Примечание: я рекомендую использовать идентификаторы вместо имен пользователей для внешних ключей для повышения производительности и практичности (не интересно, если вам нужно изменить имя пользователя).

...