В настоящее время я сталкиваюсь с трудностью, когда помещаю запятые значения в MySQL NOT IN
не дает мне результат, на который я надеялся. Там должно быть что-то, что я упускаю, так как я не уверен, что искать именно эту проблему. Выполнение только кода MySQL работает, но передача параметра из другой функции PHP — нет.
Вот код, который вызывает у меня проблему:
$uid = 1;
$selected_uids = '1,2';
$result = $db->retrieveFollowingWithCondition($uid, $selected_uids);
…тогда где-то вдоль кода …
public function retrieveFollowingWithCondition($uid, $selected_uids) {
$stmt = $this->conn->prepare("SELECT *
FROM `friendlist`
WHERE `uid` = ? AND `buddy_uid` NOT IN (?)
GROUP BY `buddy_uid`;");
$stmt->bind_param("is", $uid, $selected_uids);
...}
Я проверил, просто положив «2» в $selected_uids
и это на самом деле работает. Но как только запятая, код запускается, но $selected_uids
все еще в результате. Не уверен, что это плохая практика или просто требуется небольшая корректировка кода. Во всяком случае, я действительно с нетерпением жду, чтобы понять, почему это не работает для меня.
Используя s
в bind_param
вы говорите PHP обрабатывать все содержимое $selected_uids
как строка Следовательно, «1,2
«рассматривается как ('1,2')
вместо (1,2)
, Ваша проблема в том, что bind_param
не поддерживает массивы, поэтому поддержка IN
количество запросов ограничено. Есть несколько альтернатив, чтобы обойти это ограничение, но так как вы имеете дело со списком целых чисел, я, вероятно, сделал бы необработанную строку concat.
// using is_numeric because is_int("1") === false
$filtered = array_filter('is_numeric', $selected_uids);
// You could also just call array_map('intval', $selected_uids);
// Depending on your needs.
if(!$filtered) {
return; // No valid values
}
$filteredStr = implode(',', $filtered);
$stmt = $this->conn->prepare("SELECT *
FROM `friendlist`
WHERE `uid` = ? AND `buddy_uid` NOT IN ($filteredStr)
GROUP BY `buddy_uid`;");
Также следует отметить: если бы я пытался использовать строки для IN
запрос, я бы, вероятно, сделал следующее:
$filtered = array_map([$this->conn, 'escape_string'], $queried);
$inQuery = '\'' . implode('\',\'', $filtered) . '\'';
Я считаю, что обозначение чище и проще, чем динамически генерируемый bind_param
строка формата.
Вы должны связывать каждый параметр в IN (…) отдельно, но метод bind_param не поддерживает множественные вызовы. Есть хороший класс, который может сделать это, и вы можете найти его на страницах документации PHP:
Пользовательский класс для нескольких bind_param