Ошибка с PDO LIKE?

Ссылка скопирована
PHP
1 ответ

По вводным: есть сортировка по буквам, при клике на букву срабатывает событие получения буквы на которую кликнули через jquery

$(document).on('click', ".jq-char", function() { bk = $(this).html(); $.ajax({ url: '/admin/sortbya', type: 'POST', data: { name: bk }, cache: false, success: function (data) { console.log(data); $('.table-news').html(data); } }); });

Сейчас ситуация такая: далее уходит все в обработчик POST где я вижу что получаю это буква по которой кликнули. Но! Далее после перехода на php 8.4 почему то перестал видеть PDO отдает 500 ошибку, если в этой же функции просто что то вывести, то норм работает.

Сама функция:

// Получение всех часов с брендом на первую букву public static function allA($name) { $db = Db::getConnection(); $sql = 'SELECT * FROM watch WHERE watch_brand like :name and sold !="yes"'; $result = $db->prepare($sql); $result->bindParam(':name', "$name%", PDO::PARAM_STR); $result->setFetchMode(PDO::FETCH_ASSOC); $result->execute(); return $result->fetchAll(); }

Сейчас ситуация такая: причем прямой запрос в бд выводит все, задача получить все бренды которые начинаются на букву например H, в чем может быть проблема? До 7 версии все работало, после перехода не видит он запрос через like

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Стас DB Ответ

Ошибка с PDO LIKE чаще всего возникает из-за неправильной подстановки wildcard-символов % в prepared statement. Нельзя писать так, чтобы ожидать магическую подстановку внутри строки SQL: LIKE '%:q%'. Плейсхолдер должен быть отдельным значением, а проценты добавляются к переменной.

Правильный вариант:

$search = 'test';
$stmt = $pdo->prepare('SELECT * FROM items WHERE title LIKE :q');
$stmt->execute([
    ':q' => '%' . $search . '%',
]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

$search = 'test'; $stmt = $pdo->prepare('SELECT * FROM items WHERE title LIKE :q'); $stmt->execute([ ':q' => '%' . $search . '%', ]); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

Если используете позиционные параметры:

$stmt = $pdo->prepare('SELECT * FROM items WHERE title LIKE ?');
$stmt->execute(['%' . $search . '%']);

$stmt = $pdo->prepare('SELECT * FROM items WHERE title LIKE ?'); $stmt->execute(['%' . $search . '%']);

Если нужно искать символы % или _ как обычный текст, их нужно экранировать и добавить ESCAPE:

$search = str_replace(['\', '%', '_'], ['\\', '\%', '\_'], $search);
$stmt = $pdo->prepare("SELECT * FROM items WHERE title LIKE :q ESCAPE '\'");
$stmt->execute([':q' => '%' . $search . '%']);

$search = str_replace(['\', '%', '_'], ['\\', '\%', '\_'], $search); $stmt = $pdo->prepare("SELECT * FROM items WHERE title LIKE :q ESCAPE '\'"); $stmt->execute([':q' => '%' . $search . '%']);

Также проверьте кодировку соединения. Для русского текста база, таблица и соединение должны быть в utf8mb4. При создании PDO укажите charset:

$pdo = new PDO(
    'mysql:host=localhost;dbname=db;charset=utf8mb4',
    $user,
    $pass,
    [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);

$pdo = new PDO( 'mysql:host=localhost;dbname=db;charset=utf8mb4', $user, $pass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION] );

Отдельно смотрите collation. Если поиск должен быть нечувствительным к регистру, используйте подходящую collation вроде utf8mb4_unicode_ci или utf8mb4_general_ci. Если нужна строгая чувствительность к регистру, выбирайте binary/case-sensitive collation осознанно.

Итог: проценты добавляйте к значению параметра, а не вокруг плейсхолдера в SQL. Для поиска буквальных %/_ используйте escaping. Если LIKE не находит кириллицу, проверяйте charset, collation и то, что реально передаётся в execute(). Для отладки временно залогируйте длину поисковой строки и значение параметра без вывода персональных данных.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно