PHP БД, для чего нужны prepare и bind_param? Чем лучше mysqli_query?

Здравствуйте.
Помогите мне разобраться в php.
Не как не могу разобраться как работает ->
Вот на примере обращения к БД что лучше использовать
Вот это

$test = $db->prepare("INSERT INTO test (name1,name2,name3) VALUES (?,?,?)");
$test->bind_param("sss",$name1,$name2,$name3);
$test->execute();

или же лучше использовать вот это

$test = mysqli_query($db,"INSERT INTO test (name1,name2,name3) VALUES ($name1,$name2,$name3)");

Хотелось бы узнать почему именно то или иное использовать, так сказать узнать плюсы и минусы в этих запросах
Если сравнивать даже по размеру то второй вариант весит меньше чем первый

Первое. Чтобы не было SQL инъекций.

https://phpbestpractices.org/#mysql
https://phptherightway.com/#pdo_extension


В mysqli_ тоже можно аналогично (https://www.php.net/manual/en/mysqli.prepare.php), но нет смысла использовать mysqli_ и т.п. вместо PDO.
PDO позволяет например легко поменять СУБД (например, MySQL на PostgreSQL) почти не меняя код. Ну и новее, более продуман, больше фич.

1 лайк

С запросами понятно всё первый вариант просто более безопасный, чем второй.
А вот этот знак -> что означает?

Вызов функции (еще называют “метод”) объекта.
см. про классы, ООП.

1 лайк

2 сообщения было перенесено в новую тему: Какая разница между версиями php 5 и 7?

Есть экранирование специальных символов в строке для использования в SQL-выражении mysqli_real_escape_string. В PDO я так понимаю это можно заменить prepare
$stmt = $db->prepare("SELECT * FROM categories WHERE id = ?");
и больше экранировать не надо этим mysqli_real_escape_string?

Да.
Он либо сам сделает это, либо (в зависимости от опции PDO::ATTR_EMULATE_PREPARES) отправит значения отдельно без вставки в строку запроса.
https://phpdelusions.net/pdo#emulation

Прошу прощения за возможно глупый вопрос, но у меня есть сомнения по поводу запроса. Правильно ли я его сделал или нет (С учетом безопасности тоже)

$sql= $db->prepare('SELECT * FROM name_tab WHERE id = ? LIMIT ?');
$sql->execute([$id, 1]);
$res = $stmt->fetch();

Я так понимаю всего запросы для SELECT и INSERT они похожи, а для UPDATE и DELETE разные и в итоге у нас получается 3 всего запроса?

UPDATE

$sql = "UPDATE users SET name = ? WHERE id = ?";
$pdo->prepare($sql)->execute([$name, $id]);

DELETE

 $stmt = $pdo->prepare("DELETE FROM goods WHERE category = ?");
$stmt->execute([$cat]);
$deleted = $stmt->rowCount();

SELECT / INSERT

$sql= $db->prepare('ТУТ ПИШЕМ ИЛИ SELECT ИЛИ INSERT'); ;
$sql->execute([$id, 1]);
$res = $stmt->fetch();

Всё верно я понял?

Разные в чем именно?

prepare и execute везде одинаковые.

Всегда можно писать и так:

$pdo->prepare($sql)->execute($data);

и так:

$stmt = $pdo->prepare($sql);
$stmt->execute($data);

В первом просто сразу вызывается функция у возвращенного из первой функции объекта, без записывания его в переменную $stmt .

Тут скорее не в типе запроса дело, а в желании делать что-то после запроса: получение данных, количества строк и т.п. Без $stmt это не сделать.

Тут не весь код или не то скопировано, $stmt нигде не объявлен, а используется. :astonished:

Оу :open_mouth:
Я сейчас $smtp на $sql заменил. Так правильно же теперь стало?

$sql= $db->prepare('ТУТ ПИШЕМ ИЛИ SELECT ИЛИ INSERT'); ;
$sql->execute([$id, 1]);
$res = $sql->fetch();

Ага … кажется до меня дошло всё
$db->prepare - тут мы подключаемся к БД и заодно проверяем на безопасность всяких SQL-инекций
execute - это за место mysqli_query
fetch - это тут что то подобное mysqli_fetch_assoc (mysqli_fetch_assoc написал как пример.)

Да, но stmt (statement, от prepared statement) более понятное имя и по привычности, и по смыслу.
sql это скорее строка с запросом (кодом на языке SQL).

Я сверху не много дополнил. И по поводу stmt и sql тут могут быть любые же переменные понятные по смыслу для чего они. Просто если на одной странице несколько запросов одну переменную не очень как то использовать

Не знаю что там внутри PDO делает, но подключение думаю не обязательно на этом этапе.

Тут создается “подготовленный запрос” (либо настоящий в СУБД, либо эмуляция, как выше написано).

https://en.wikipedia.org/wiki/Prepared_statement

И потом execute этот запрос выполняет.

Скорее не вместо, а нечто другое, потому что в mysqli_ функциях тоже есть функции для prepared statement.


Можно ж функции создавать ) getProducts(), insertProduct($name, $price), …

1 лайк

Спасибо огромное за разъяснения. Пойду дальше читать и просвещаться.
Ваш форум зачет. Не на одном форуме не получал так оперативно ответы и так подробно. В закладках теперь этот форум самый первый