См. Ниже мой код. Я пытаюсь связать массив парадоксов с моим подготовленным заявлением. Я просматривал в Интернете и вижу, что мне нужно использовать call_user_func_array, но не могу заставить его работать. Ошибка, которую я получаю: «Первый аргумент, как ожидается, будет действительным обратным вызовом,« Array »было указано« Возможно, я ошибаюсь, но я предполагаю, что первым аргументом может быть массив, и, возможно, это сообщение об ошибке вводит в заблуждение. Я думаю, что проблема заключается в том, что мой массив в чем-то виноват. Может ли кто-нибудь увидеть, что я делаю неправильно? Благодарю.
$type = array("s", "s"); $param = array("string1","anotherstring"); $stmt = $SQLConnection->prepare("INSERT INTO mytable (comp, addl) VALUES (?,?)"); $params = array_merge($type, $param); call_user_func_array(array(&$stmt, 'bind_param'), $params); $SQLConnection->execute();
Я не знаю, почему вы должны использовать call_user_func_array
, но это еще одна история.
Единственное, что может быть неправильным в моих глазах, это то, что вы используете ссылку на объект. Предполагая, что вы используете PHP 5. *, это необязательно:
call_user_func_array(array($stmt, 'bind_param'), $params);
Это должно быть так:
//connect $mysqli = new mysqli($host, $user, $password, $db_name); //prepare $stmt = $mysqli->prepare("SELECT * FROM the_table WHERE field1= ? AND Field2= ?"); //Binding parameters. Types: s = string, i = integer, d = double, b = blob $params= array("ss","string_1","string_2"); //now we need to add references $tmp = array(); foreach($params as $key => $value) $tmp[$key] = &$params[$key]; // now us the new array call_user_func_array(array($stmt, 'bind_param'), $tmp); $stmt->execute(); /* Fetch result to array */ $res = $stmt->get_result(); while($row = $res->fetch_array(MYSQLI_ASSOC)) { $a_data[]=$row; } print_r($a_data); $stmt->close();
Не смог ответить на мой вопрос, потому что он был отмечен как обман: здесь . Но я думаю, что мое окончательное решение, которое использует ответы в этом вопросе, работает в моем случае использования, может быть полезно для кого-то.
Мои цели состояли в том, чтобы взять опубликованный набор идентификаторов и использовать их в инструкции NOT IN
MYSQL. Предположим, что массив из 5 идентификаторов отправлен.
Подсчитайте число, отправленное ID, чтобы построить ?
заполнители для заявления NOT IN
. Используя $params_count = substr(str_repeat(',?', count($array_of_ids)), 1);
дает результат: (?,?,?,?,?)
который будет использоваться в инструкции SQL.
Сделайте функцию, которая принимает идентификаторы и тип i
или s
и т. Д. Для меня все они были такими, что моя функция проще. возвращаемый массив, который выглядит так: $params= array("iiiii",1,2,3,4,5)
где первым значением является набор i
, а последующие значения – это ID в зависимости от общего количества идентификаторов, передаваемых в функцию ,
function build_bind_params($values, $bind_type) { $s = substr(str_repeat($bind_type, count($values)), 0); $bind_array = array(); $bind_array[] = $s; foreach($values as $value) { $bind_array[] = $value; } return $bind_array; }
$params = build_bind_params($array_of_ids, "i");
Затем используйте foreach ($params as $key => $value) $tmp[$key] = &$params[$key];
чтобы получить вновь созданные $params
правильно отформатированные для привязки.
Затем используйте call_user_func_array(array($stmt , 'bind_param') , $tmp);
для правильной привязки массива.
Затем выполните $stmt
Почему вы хотите вызвать call_user_func_array (массив ($ statement, 'bind_param'), $ bind_arguments)? Поскольку $ bind_arguments – это массив. У вас есть одна функция, которая связывает оператор с его запрошенными параметрами, независимо от того, сколько параметров у вас было бы в противном случае.
Пример хорошего кода …
<?php # link $dblink = new mysqli('HOSTNAME','USERNAME','PASSWORD','DATABASENAME'); # example data $statement = $dblink->prepare("SELECT * from Person WHERE FirstName = ? AND MiddleName = ? AND LastName = ? and Age = ?"); $recordvalues = ['John', 'H.', 'Smith', 25]; $sqlbindstring = "sssi"; # String, String, String, Integer example # make the references $bind_arguments = []; $bind_arguments[] = $sqlbindstring; foreach ($recordvalues as $recordkey => $recordvalue) { $bind_arguments[] = & $recordvalues[$recordkey]; # bind to array ref, not to the temporary $recordvalue } # query the db call_user_func_array(array($statement, 'bind_param'), $bind_arguments); # bind arguments $statement->execute(); # run statement $result = $statement->get_result(); # get results # get the results if($result) { while ($row = $result->fetch_assoc()) { print("\n\nMy row is..."); print_r($row); } } ?>
Пример плохого кода …
<?php # Same setup as above.. $statement->prepare("SELECT * from Person WHERE FirstName = ? AND MiddleName = ? AND LastName = ? and Age = ?"); $statement->bind('John', 'H.", 'Smith', 25); ?>
В первом примере: вы можете передать столько или меньше привязки для выполнения, чтобы bind () мог быть вызван только в одной строке всего вашего приложения. Это хорошо масштабируется.
Во втором примере: вы должны написать оператор bind () для каждой возможной группы вставок для каждой возможной записи в вашей базе данных. Это плохо масштабируется.
Если вы получили сообщение об ошибке, попробуйте это:
call_user_func_array(array($stmt, 'bind_param'), refValues($params)); function refValues($arr){ if (strnatcmp(phpversion(),'5.3') >= 0) { $refs = array(); foreach($arr as $key => $value) $refs[$key] = &$arr[$key]; return $refs; } return $arr; }