Параметры привязки MySQLI с помощью call_user_func_array

См. Ниже мой код. Я пытаюсь связать массив парадоксов с моим подготовленным заявлением. Я просматривал в Интернете и вижу, что мне нужно использовать 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(); 

Related of "Параметры привязки MySQLI с помощью call_user_func_array"

Я не знаю, почему вы должны использовать 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 идентификаторов отправлен.

  1. Подсчитайте число, отправленное ID, чтобы построить ? заполнители для заявления NOT IN . Используя $params_count = substr(str_repeat(',?', count($array_of_ids)), 1); дает результат: (?,?,?,?,?) который будет использоваться в инструкции SQL.

  2. Сделайте функцию, которая принимает идентификаторы и тип 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");

  1. Затем используйте foreach ($params as $key => $value) $tmp[$key] = &$params[$key]; чтобы получить вновь созданные $params правильно отформатированные для привязки.

  2. Затем используйте call_user_func_array(array($stmt , 'bind_param') , $tmp); для правильной привязки массива.

  3. Затем выполните $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; }