У меня есть функция, которая делает это:
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 ); } }