Я избиваю голову над синтаксической ошибкой ниже. Я пытаюсь связать вмонтированный массив в подготовленный оператор, но я получаю следующую синтаксическую ошибку:
У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с?? в строке 1
Вот мой код. Может ли кто-нибудь увидеть, где я ошибаюсь?
<?php include('config.php'); $selected = $_POST['selected']; if ($stmt = $mysqli->prepare("DELETE FROM email_addresses WHERE email_addresses IN ?")) { $stmt->bind_param("s", "('" . implode("', '", $selected) . "')" ); $stmt->execute(); $stmt->close(); print "ok"; } else { print $mysqli->error; } $mysqli->close(); ?>
В качестве теста я попытался:
print "('" . implode("', '", $selected) . "')";
Что правильно дает мне
('me@me.com', 'you@you.com')
Позвольте мне сэкономить вам неприятности и рассказать вам, что вы пытаетесь сделать, в любом случае не сработает. Вы привязываете только один параметр к вызову функции IN()
. Вы думаете , что передаете список, разделенный запятыми, но на самом деле вы передаете только разделенную запятыми строку, которая рассматривается как одно значение . Это означает, что вы будете искать одну запись со значением «me@me.com», «you@you.com» вместо записей, соответствующих «me@me.com» или «you@you.com», ,
Чтобы преодолеть это, вам необходимо:
call_user_func_array()
для привязки параметров Вы можете сгенерировать строки типов следующим образом:
$types = str_repeat('s', count($selected));
Все это создает строку s
, которая имеет столько же символов, сколько количество элементов в массиве.
Затем вы связываете свои параметры с помощью call_user_func_array()
следующим образом (обратите внимание, что я вернул скобки для функции IN()
):
if ($stmt = $mysqli->prepare("DELETE FROM email_addresses WHERE email_addresses IN (?)")) { call_user_func_array(array($stmt, "bind_param"), array_merge($types, $selected));
Но если вы попробуете это, вы получите сообщение об ошибке mysqli_stmt::bind_param()
ожидая, что параметр два будет передан по ссылке:
Предупреждение: Параметр 2 для mysqli_stmt :: bind_param () должен быть ссылкой, значение указано
Это немного раздражает, но достаточно легко для работы. Чтобы обойти это, вы можете использовать следующую функцию:
function refValues($arr){ $refs = array(); foreach($arr as $key => $value) $refs[$key] = &$arr[$key]; return $refs; }
Он просто создает массив значений, которые ссылаются на значения в $selected
array. Этого достаточно, чтобы сделать mysqli_stmt::bind_param()
счастливым:
if ($stmt = $mysqli->prepare("DELETE FROM email_addresses WHERE email_addresses IN (?)")) { call_user_func_array(array($stmt, "bind_param"), array_merge($types, refValues($selected)));