@Billy_Milligan

Как в MySQLi сделать поиск по параметрам, если их количество неизвестно?

Решил переписать запросы.
1) Теперь не понятно, как сделать поиск по параметрам, если их количество неизвестно.

Раньше можно было сделать так:

"... IN ( ".implode(',',$paraqms)." ) ..."

Как это можно сделать средствами mysqli?

2) Как ловить ошибки.

Раньше можно было просто:

if($result)...

Сейчас это выглядит так:

if($stmt->prepare("
            SELECT `user_id`,`password` 
            FROM `user` 
            WHERE `email` = ?") === FALSE
    
        OR $stmt->bind_param('s', $email) === FALSE
        OR $stmt->execute() === FALSE
        OR $stmt->bind_result($id,$password_db) === FALSE
        OR $stmt->store_result() === FALSE
        OR $stmt->fetch() === FALSE
        OR $stmt->close() === FALSE) {

        //продолжаем, ошибок нет
    } else { echo "что то пошло не так!";}


Сам понимаю, что конструкция ужасная и так делать нельзя, но это всё что пришло в голову.

3) Как грамотно оформить такую конструкцию или так нормально? Не нравится мне 100500 переменных.

$stmt = $mysqli->stmt_init();
    $stmt->prepare("
            INSERT INTO `MyTable` (`a`, `b`, `c`, `d`) 
            VALUES (?, ?, ?, ?)");
    
    $stmt->bind_param('iiii', $id, $a, $b, $c);

    foreach($array_1 as $i => $chtoto) {
        $a = $chtoto;
        $b = $array_2[$i];
        $c = $array_3[$i];
        $stmt->execute();
    }
    $stmt->close();
  • Вопрос задан
  • 2846 просмотров
Решения вопроса 1
FanatPHP
@FanatPHP
Чебуратор тега РНР
1. И сейчас можно, только надо делать по уму.
Совсем не обязательно упираться в родные препареды. Их вполне можно эмулировать. Поэтому подключаем safeMysql и пишем для первого запроса
$data = $db->getAll("SELECT * FROM t WHERE id IN (?a)", $params);
а для второго
$sql = "SELECT user_id,password FROM user WHERE email = ?s";
$row = $db->getRow($sql, $email);
2. if($result) не нужно было делать и раньше. Если база даёт сбой - это гарантированный фейл, и надо аварийно завершать работу. А не писать "что-то пошло не так" и продолжать долбить неработающую базу запросами.

В отдельных исключительных случаях можно ловить исключение. Но именно как исключение, а не правило.

Если работаем с голым mysqli (что не рекомендуется), перед коннектом надо написать вот это
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
и после этого ловить ошибки в error handler-е или блоке catch.

3. Посмотрел повнимательнее. Это единственный из всех приведенных кейсов, в котором использование родных препаредов оправдано. В принципе - да, так и делать. Особо тут не ничего не придумаешь. Mysqli умеет биндить только переменные и только по ссылке. Для одноразового использования можно написать враппер, который будет биндить переменное число плейсхолдеров. Но вот для выполнения подготовленного запроса в цикле - только так. PDO же умеет биндить по значению, и позволяет немного сократить код
foreach($array_1 as $id => $chtoto) {
    $stmt->execute([$id, $chtoto, $array_2[$i],$array_3[$i]]);
}
Как вариант, можно сформировать мультиинсерт опять же с помощью safeMysql:
$ins = array();
foreach($array_1 as $id => $chtoto) {
    $ins[] = $db->parse("(?i,?i,?i,?i)",$id, $chtoto, $array_2[$i],$array_3[$i]);
}
$instr = implode(",",$ins);
$db->query("INSERT INTO `MyTable` (`a`, `b`, `c`, `d`) VALUES ?p", $instr);
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы