Bind Param с массивом параметров

У меня есть функция, которая делает это:

function registerUser($firstName, $lastName, $address, $postcode, $email, $password) { $params = array($firstName, $lastName, $address, $postcode, $email, $password); $result = $this->db->bind("INSERT INTO Users VALUES (?, ?, ?, ?, ?, ?)", 'ssssss', $params); } 

Что отправляется в мой класс базы данных, который делает это:

 public function bind($query, $type, $params) { $this->query = $query; $stmt = $this->mysqli->prepare($this->query); $stmt->bind_param($type, $param); $stmt->execute; } 

Проблема в том, что это не работает.

То, что я надеялся сделать, заключалось в том, чтобы взять список $params и перечислить их после $type , чтобы запрос был похож:

 $stmt->bind_param('ssssss', $firstName, $lastName, $address, $postcode, $email, $password); 

Но, очевидно, я ошибаюсь.

есть ли способ сделать массив … как бы преобразованным в список, который будет распечатан на bind_param запроса bind_param ?

call_user_func_array() !

 call_user_func_array(array($stmt, "bind_param"), array_merge(array($type), $params)); 

должен выполнять работу

UPDATE : вы также должны изменить свой массив params:

 $params = array(&$firstName, &$lastName, &$address, &$postcode, &$email, &$password); 

поскольку mysqli_stmt::bind_param ожидает второй и следующие параметры по ссылке.


EDIT: Ваш запрос кажется неправильным. Возможно, у вас меньше полей, чем у вас есть переменные. Делать:

 "INSERT INTO Users (field1, field2, field3, field4, field5, field6) VALUES (?, ?, ?, ?, ?, ?)" 

где вы заменяете имя полей правильными именами

Начиная с PHP 5.6 вы можете использовать распаковку аргументов в качестве альтернативы call_user_func_array и часто в 3-4 раза быстрее.

 $func = 'foo'; $values = array(1, 2); call_user_func_array($func, $values); //returns 3 $func(...$values); //returns 3 ?> 

Взято отсюда .

Поэтому ваш код должен выглядеть примерно так:

 public function bind($query, $type, $params) { $this->query = $query; $stmt = $this->mysqli->prepare($this->query); $stmt->bind_param($type, ...$params); $stmt->execute; } 

Вы получаете свою ошибку «Вызовите функцию-член bind_param () для не-объекта», скорее всего, потому что ваш метод $ this-> mysqli-> встречает какую-то ошибку. (см. http://php.net/manual/de/mysqli.prepare.php – он возвращает FALSE при ошибке, что, как представляется, здесь)

После устранения этой проблемы попробуйте это вместо вашего вызова $ stmt-> bind_param:

 call_user_func_array(array($stmt, 'bind_param'), array_merge($type, $params)); 

Самый простой способ – переход от mysqli к PDO

Это позволит вам сделать это так, как вы хотите, и даже без каких-либо дополнительных функций:

 function registerUser($firstName, $lastName, $address, $postcode, $email, $password) { $sql = "INSERT INTO Users VALUES (NULL, ?, ?, ?, ?, ?, ?)"; $stmt = $this->db->prepare($sql); $stmt->execute(func_get_args()); } 

Важно отметить, что mysqli_stmt_bind_param() требует, чтобы параметры передавались по ссылке, поэтому параметры для call_user_func_array() должны быть ссылкой. Пример, взятый из контекста класса:

 function execute( string $query, string $type, array $params ) { if ( !$stmt = $this->mysqli->prepare( $query ) ) throw new \Exception( 'Prepare failed: ' . $query . PHP_EOL . $this->mysqli->error ); // call stmt->bind_param() with variables to bind passed as a reference call_user_func_array( array( $stmt, 'bind_param' ), array_merge( array( $type ), array_map( function( &$item ) { return $item; }, $params ) ) ); if ( !$stmt->execute() ) throw new \Exception( 'Execute failed: ' . PHP_EOL . $stmt->error ); } }