Следующий устаревший код, предназначенный для переделки у нас находится в строке 62
$from = $user_id ? $login : mysql_real_escape_string($name);
Это интересный и ВАЖНЫЙ момент, ибо он связан не с самим запросом, а с экранированием его данных, для предотвращения SQL инъекции и взлома Вашего сайта.
В старом коде для этого у нас была функция mysql_real_escape_string()
В PDO для достижения той же цели, можно пойти несколькими путями...
1) Простейший путь - это применить вместо устаревшей функции ее аналог $db->quote() и строка в этом случае будет выглядеть так:
$from = $user_id ? $login : $db->quote($name);
Однако $db->quote не полный аналог mysql_real_escape_string(), ибо он кроме экранирования кавычек внутри строки, еще и берет в кавычки саму строку. Следовательно нам надо будет переделать еще и запрос, убрав кавычки вокруг вставляемой переменной.
2) Другой и более правильный путь - это подготовленный запрос, который мы сейчас и будем реализовывать.
===
Итак, решил делать подготовленный запрос.
В начале я осмотрел дальнейший код на предмет, ГДЕ используется наша переменная $from и нашел нужный запрос, который в строке 120 и который надо переделать на подготовленное выражение. Для этого применяем метод $db->prepare() и заменяем все переменные в запросе на простые плейсхолдеры ? (знак вопроса). Есть еще именованные плейсхолдены, но их рассмотрим отдельно.
Старый код запроса временно где-то сохраняем, ибо нам понадобятся оттуда переменные.
После переделки на подготовленный запрос, код будет выглядеть так:
$stmt = $db->prepare("INSERT INTO `guest` SET
`adm` = ?,
`time` = ?,
`user_id` = ?,
`name` = ?,
`text` = ?,
`ip` = ?,
`browser` = ?,
`otvet` = ''
");
Обратите внимание на строку `otvet` = '', там передается пустое значение, поэтому я не стал ставить плейсхолдер а применил прямой запрос. То же самое можно делать, если передаете фиксированное числовое значение, к примеру `otvet` = 5
А для всех "опасных" данных, нужны плейсхолдеры.
Но это пока только подготовленное выражение, которое ничего не добавит в базу и которому мы пока не передали никаких данных. займемся этим. Нам нужно передать подготовленному запросу реальные данные и запустить его на выполнение (вставить запись в базу данных). Для этого применяем $stmt->execute(); в который в виде массива передаются наши данные, которые мы заменили плейсхолдерами.
ОЧЕНЬ ВАЖНО, чтоб данные в массиве находились именно в той последовательности, как у нас размещены плейсхолдеры, не перепутайте!
В итоге сравним что было и что стало:
СТАРЫЙ ЗАПРОС:
mysql_query("INSERT INTO `guest` SET
`adm` = '$admset',
`time` = '" . time() . "',
`user_id` = '" . ($user_id ? $user_id : 0) . "',
`name` = '$from',
`text` = '" . mysql_real_escape_string($msg) . "',
`ip` = '" . core::$ip . "',
`browser` = '" . mysql_real_escape_string($agn) . "',
`otvet` = ''
");
НОВЫЙ ПОДГОТОВЛЕННЫЙ ЗАПРОС
$db->prepare("INSERT INTO `guest` SET
`adm` = ?,
`time` = ?,
`user_id` = ?,
`name` = ?,
`text` = ?,
`ip` = ?,
`browser` = ?,
`otvet` = ''
")->execute([
$admset,
time(),
($user_id ? $user_id : 0),
$from,
$msg,
core::$ip,
$agn,
]);
ВАЖНО: в подготовленном запросе не надо экранировать данные, то, что мы делали с помощью mysql_real_escape_string(). Более того, если вспомним строку 62, мы с нее тоже должны убрать экранировку.
Итого, после доработки в репозитории у нас следующее:
Строка 62:
https://github.com/john-cms/jo ... p#L62
Подготовленный запрос:
https://github.com/john-cms/jo ... -L137
Можно работать дальше