Всем привет. Пошел 6-й месяц, как я учусь делать сайты. Сейчас делаю сайт для себя и решил переписать все 100+ страниц с MYSQL на PDO (только ради плейсхолдеров). Запросы типа WHERE id=$var AND user=$var2 и т.д без проблем все переписал, но сейчас добрался до страниц, которые я писал на MYSQL и пользуясь легкостью вставки в запрос целых выражений в переменных исходящих из условных операторов, создал такой клубок, что мне кажется PDO с ним не разберется... Помогите советом! Как это все распутать и можно ли распутать...
ЗАПРОС:
$result = mysql_query("SELECT * FROM tovar ".$var1." vid='1' $var2 $var3 $var4 $var5 $var6 $var7 GROUP BY products_id ORDER BY $var8 $var9");
ГДЕ:
$var1 это
`IF что то 'JOIN table WHERE id = other_id AND значение IN('.$var из другого запроса .')' AND '$var2 из другого запроса = 'DISTINCT id''
else
'WHERE' AND '$var4 из другого запроса = '*' AND $var3 из другого запроса = ''
И примерно такие же $var2, $var3, $var4, $var5, $var6, $var7, $var8, $var9,
Как думаете можно этот клубок распутать на PDO или проще повеситься?
Да я то могу в них разобраться, а вот PDO ругается. Разматывать надо конечно по одной ниточке. Вот к примеру как сделать это?
if ($_GET['up'] == 'one') $go_see = "AND see='1'"
$count = $db->prepare("SELECT COUNT(*) FROM tovar WHERE vid='1' $go_see ''");
$count->execute([ ': go_see' => ??? ]);
Вариант просто вставить в запрос AND see=:плейсхолдер где ': плейсхолдер ' => 1 и убрать таким образом переменную из запроса слишком очевиден и соответственно не подходит. Переменная $go_see может быть пустой или вместо AND иметь OR
И попутно еще вопрос. Будет ли безопасным такой вариант запроса?
$go_see= 'AND see=1';
$db->query("SELECT * FROM tovar WHERE vid='1' $go_see");
Везде пишут, что если в запросе есть переменная, то он уязвим! Это относится даже к тем переменным, которые назначаются внутри скрипта без использования внешних данных?
По хорошему, Вам нужно внедрить какой-никакой SqlBuilder.
Можно, конечно, строить запросы вручную:
$where = [];
$params = [];
$where[] = 'vid = ?';
$params[] = '1';
if ($_GET['up'] == 'one') {
$where[] = 'see = ?';
$params[] = 1;
}
if (!empty($_GET['ids'])) {
$values = preg_split('/\s*,\s*/', $_GET['ids']);
if (!empty($values)) {
$in = str_repeat('?,', count($values)-1).'?';
$where[] = "id in ($in)"; // Только плейсхолдеры попадают в запрос
$params = array_merge($params, $values);
}
}
$where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
$sql = "SELECT COUNT(*) FROM tovar $where";
// SELECT COUNT(*) FROM tovar WHERE vid = ? AND see = ? AND id IN (?,?,?)
$stmt = $db->prepare($sql);
$stmt->execute($params);
Константы или значения из белого списка совершенно необязательно отделять от запроса, тем не менее - это хорошая привычка.
Переписывать запросы однозначно. Вы же сами в них не можете разобраться. Если есть проблемы с переписыванием - задавайте вопросы и приводите конкретные примеры
Сборка персонального компьютера от Artline: умный выбор для современных пользователей