привязка регулярного выражения к параметру PDO в инструкции PDO - PullRequest
3 голосов
/ 24 декабря 2011

Хорошо, я довольно новичок в php и mysql.Я создаю PHP-интерфейс для базы данных MySQL.Я использую драйвер PDO для доступа к базе данных, так как он предотвращает атаки SQL инъекций.Пока все было хорошо, пока я не пришел к этой проблеме.У меня есть функция поиска, где пользователь может вводить название компании полностью или частично для поиска данных о ней.

Вот оператор PDO, который я использую для поиска в базе данных:

SELECT CompName FROM CompanyName 
WHERE CompName REGEXP :name 
ORDER BY CompName ASC LIMIT 1

Так что тогда я могу подготовить, привязать, какие пользовательские типы в поле поиска к имени параметра, и выполнить инструкцию.Пока пользователь не вводит метасимволы, это работает.Вот самое простое регулярное выражение, которое я вставляю в оператор PDO вместо name:
^ whatusertyped - так как изначально я ищу полное совпадение.Поскольку некоторые названия компаний содержат точки, я хочу, чтобы пользователь мог печатать эти символы и мое регулярное выражение, чтобы они воспринимались как литералы, а не как метасимволы.Итак, вот как я заменял метасимволы, чтобы получить их буквальное значение:

типы пользователей: C. чтобы найти название компании, которое начинается с C.

php-функция вставляет ^ и \\\\ чтобы получить вывод ^ C \\.

mysql получает: ^ C \\.и ищет C. в начале названия компании, где точка буквальна и не означает «искать символ подстановки».

Итак, я пытаюсь найти C. потому что в базе данных есть компания, чье имя начинается так, и я должен получить совпадение, но я не получаю, оператор PDO возвращает пустой массив.

Я попробовал запрос:

SELECT CompName FROM CompanyName 
WHERE CompName REGEXP "^C\\\\." 
ORDER BY CompName ASC LIMIT 1

прямо в mysql и получил совпадение, а также я непосредственно выполнил запрос в PHP без подготовки, связывания и возврата совпадения.Мне кажется, что проблема заключается в подготовке и привязке поискового термина к параметру, но я не смог понять, что это такое и как его решить.Я действительно хочу использовать связывание и подготовку, как я сказал, чтобы избежать инъекций sql.

Любая помощь будет принята с благодарностью.Надеюсь, я четко объяснил проблему.

1 Ответ

4 голосов
/ 24 декабря 2011

Я считаю, что значение, которое вы связываете с :name, должно быть просто ^C\., а не ^C\\.. Вам не нужно делать экранирование для уровня sql , только для уровня regex (т.е. \. для буквального .).

Также рассмотрите возможность использования WHERE CompName LIKE 'C.%'. Вам не нужно регулярное выражение здесь. Вы бы использовали так:

function like_escape($s) {
// Do like-expression escaping
    return addcslashes($s, '%_');
}
$searchprefix = 'C.';
$sql = 'SELECT CompName FROM CompanyName WHERE CompName LIKE ? ORDER BY CompName ASC';
$stmt = $db->prepare($sql);
$likeclause = like_escape($searchprefix).'%';
$db->bindValue(1, $likeclause, PDO::PARAM_STR);
$stmt->execute();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...