Я должен выбрать некоторые строки из базы данных с помощью оператора IN
. Я хочу сделать это, используя подготовленный оператор. Это мой код:
<?php $lastnames = array('braun', 'piorkowski', 'mason', 'nash'); $in_statement = '"' . implode('", "', $lastnames) . '"'; //"braun", "piorkowski", "mason", "nash" $data_res = $_DB->prepare('SELECT `id`, `name`, `age` FROM `users` WHERE `lastname` IN (?)'); $data_res->bind_param('s', $in_statement); $data_res->execute(); $result = $data_res->get_result(); while ($data = $result->fetch_array(MYSQLI_ASSOC)) { ... } ?>
Но ничего не возвращает, хотя все данные существуют в базе данных.
И еще один: если я $in_statement
напрямую, чтобы запросить и выполнить его, данные будут возвращены. Поэтому проблема возникает при подготовке.
Я искал вопрос в Google, но он не был «успешным». Что случилось с моим кодом?
Спасибо за помощь!
Недавно я нашел решение для моего вопроса. Возможно, это не лучший способ сделать это, но он работает хорошо! Докажи, что я неправ:)
<?php $lastnames = array('braun', 'piorkowski', 'mason', 'nash'); $arParams = array(); foreach($lastnames as $key => $value) //recreate an array with parameters explicitly passing every parameter by reference $arParams[] = &$lastnames[$key]; $count_params = count($arParams); $int = str_repeat('i',$count_params); //add type for each variable (i,d,s,b); you can also determine type of the variable automatically (is_int, is_float, is_string) in loop, but i don't need it array_unshift($arParams,$int); $q = array_fill(0,$count_params,'?'); //form string of question marks for statement $params = implode(',',$q); $data_res = $_DB->prepare('SELECT `id`, `name`, `age` FROM `users` WHERE `lastname` IN ('.$params.')'); call_user_func_array(array($data_res, 'bind_param'), $arParams); $data_res->execute(); $result = $data_res->get_result(); while ($data = $result->fetch_array(MYSQLI_ASSOC)) { ... } $result->free(); $data_res->close(); ?>
Подготовленные заявления предназначены для того, чтобы точно избежать того, что вы пытаетесь сделать. 🙂
Чтобы заставить это работать, вы должны применить этот шаг:
$escaped_lastnames = join(',', array_map(array($_DB, 'real_escape_string'), $lastnames));
Он отображает правильную функцию экранирования строки для вашей базы данных по каждому элементу $lastnames
. Когда это будет сделано, вы вставляете это значение прямо в запрос, то есть без использования связанных параметров.