Я использую построитель запросов в своем проекте Symfony для индексации всех моих физических лиц, используя несколько параметров, таких как имя, фамилия, адрес...
У каждого человека может быть максимум 3 имени. Я использую select2 в своей форме, чтобы позволить пользователю писать несколько имен в одном поле ввода.
Все работает, за исключением того факта, что если я набираю в поле символ с акцентом (например, Реми), я получаю следующую ошибку:
[Syntax Error] line 0, col 730: Error: Expected end of string, got 'é'
Я перепробовал все, но не могу найти ошибку. Вот код в моем PersonRepository, который управляет параметром имени:
if (!empty($firstNames)) {
$orConditions = $qb->expr()->orX();
foreach ($firstNames as $firstName) {
$orConditions->add(
$qb->expr()->like('LOWER(ip.firstName)', ':firstName' . $firstName)
);
$qb->setParameter(':firstName' . $firstName, '%' . mb_strtolower($firstName, 'UTF-8') . '%');
}
$qb->andWhere($orConditions);
}
Можете ли вы мне помочь, ребята?
Привет, Крис, я сделал это, но ошибка все равно :(
Что касается второй части изменения, вы обновили его в обоих местах?
Да, вот код: if (!empty($prenoms)) { $orConditions = $qb->expr()->orX(); foreach ($prenoms as $key => $prenom) { $orConditions->add( $qb->expr()->like('LOWER(ip.prenom)', ':prenom_' . $key) ); $qb->setParameter(':prenom_' . $key, '%' . mb_strtolower($prenom, 'UTF-8') . '%'); } $qb->andWhere($orConditions); }
Хм... не могли бы вы осмотреть $key, что там? Я предполагаю, что это просто целые числа, начинающиеся с 0, но могу ошибаться.
Ключ имеет то же значение, что и значение $firstName, поэтому я просто использовал foreach ($firstNames как $firstName)
О, я только что узнал! Параметр не может иметь акцентированный символ «:firstName». $firstName, Так что мне просто пришлось убрать акценты в имени для этого случая, чтобы параметр работал нормально :)
Я опубликовал ответ, который делает нечто подобное, но предлагает лучший контроль над вводом пользователя.
@AureSanta, разве вы не понимаете, что, добавляя значения к именам-заполнителям, вы делаете бесполезной всю защиту от SQL-инъекций?
Здравствуйте, да, я отредактировал свой код, чтобы обезопасить его :)






Судя по вашим комментариям, я думаю, что это должно сработать. Поскольку ключи вашего массива совпадают со значениями, мы просто будем отслеживать индекс вручную.
То, как вы строите параметры, вы фактически создаете :prenom_Rémy, и похоже, что вы не можете использовать такие символы в заполнителях/параметрах.
В вашем комментарии упоминалось просто об удалении акцентов, однако вместо этого я бы рекомендовал использовать что-то, что вы можете лучше контролировать, например увеличивающееся число.
if (!empty($prenoms)) {
$orConditions = $qb->expr()->orX();
$idx = 0;
foreach ($prenoms as $prenom) {
$orConditions->add($qb->expr()->like('LOWER(ip.prenom)', ':prenom_'.$idx));
$qb->setParameter(':prenom_'.$idx, '%'.mb_strtolower($prenom, 'UTF-8').'%');
$idx++;
}
$qb->andWhere($orConditions);
}
Привет, Крис, твой подход лучше моего, большое спасибо за потраченное на него время, хорошего дня! :)
Вместо
foreach ($firstNames as $firstName)можно использоватьforeach ($firstNames as $idx => $firstName), а потом вместо':firstName' . $firstNameиспользовать':firstName' . $idx? По крайней мере, если я правильно читаю.