dazle
@dazle
Хороший электрик, но в душе программист

Проблема с SQL иньекциями. Не работает с 2 запросами в бд. Почему?

Вот этот код рабочий, но в нем есть запрос в бд с 1 переменной которая не проходит через бинд параметр:
include("bd.php");
session_start();
$id=$_SESSION['id'];
 
$row=mysqli_query($bd, "SELECT * FROM `users` WHERE `id`='$id' ");
$c=mysqli_fetch_array($row);
 
 $h=$c['rey'];
 $avatar=$c['avatar'];
 $login=$c['name'];

 //Добавляем все в таблицу
 $res=mysqli_prepare($bd, "INSERT INTO `messages` (`avatar`,`login`,`rey`,`message`) VALUES
(?,?,?,?) ");

mysqli_stmt_bind_param($res, 'ssis', $avatar, $login, $h, $mess); 

mysqli_stmt_execute($res);

А вот этот код не рабочий когда я биндю 2 запроса в бд:
include("bd.php");	
session_start();
$id=$_SESSION['id'];

$row=mysqli_prepare($bd, "SELECT * FROM `users` WHERE id=? ");

mysqli_stmt_bind_param($row, 'i', $id); 

mysqli_stmt_execute($row);

$c=mysqli_fetch_array($row);
 
 $h=$c['rey'];
 $avatar=$c['avatar'];
 $login=$c['name'];

//Добавляем все в таблицу
 $res=mysqli_prepare($bd, "INSERT INTO `messages` (`avatar`,`login`,`rey`,`message`) VALUES
(?,?,?,?) ");

mysqli_stmt_bind_param($res, 'ssis', $avatar, $login, $h, $mess); 

mysqli_stmt_execute($res);
  • Вопрос задан
  • 228 просмотров
Решения вопроса 1
FanatPHP
@FanatPHP
Чебуратор тега РНР
Это да, косяк mysqli, совершенно неочевиное поведение. Стейтмент не позволяет использовать станартный фетч. Нужно сначала получить результат запроса, а потом уже фетчить.

Код пишу в нормальном синтаксисе, потому что от вида этих бесконечных mysqli_stmt_bind_param_stmt_execute_mysqli_stmt_param_fetch_execute у меня начинают болеть зубы.

$stmt = $bd->prepare("SELECT * FROM `users` WHERE id=? ");
$stmt->bind_param('i', $id); 
$stmt->execute();
$res = $stmt->get_result(); // вот это
$row = $res->fetch_assoc();


Вообще, пользоваться чистым синтаксисом mysqli может только мазохист. Поскольку это низкоуровневая библиотека, которая раскладывает каждую задачу на кучу мелких операций. Все эти операции нужны, без них нельзя обойтись. Но совершенно не оябзательно как попугай постоянно долдонить их в каждом запросе. Можно написать функцию, которая будет выполнять их внутри.
$row = prepared_select($bd, "SELECT * FROM `users` WHERE id=?", [$id])->fetch_assoc();


Но самое, конечно, смешное - это что SELECT запрос тебе здесь не нужен.
Базы данных работают совсем по-другому. Тебе не надо перекладывать данные из одной таблички в другую. Твоя БД потому называтся реляционной, что в ней можно связывать таблицы. И получать данные на основании связей. То есть в таблице messages не нужны ни имя. ни аватарка. Нужен только id юзера. А все его причиндалы ты получишь потом, при выводе, из таблицы users, используй JOIN запрос.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы