J'ai une fonction qui fait ceci:
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);
}
Ce qui envoie à ma classe de base de données, qui fait ceci:
public function bind($query, $type, $params)
{
$this->query = $query;
$stmt = $this->mysqli->prepare($this->query);
$stmt->bind_param($type, $param);
$stmt->execute;
}
Le problème est que cela ne fonctionne pas.
Ce que j'espérais faire était de prendre la liste $params
et de la lister après le $type
, afin que la requête ressemble à ceci:
$stmt->bind_param('ssssss', $firstName, $lastName, $address, $postcode, $email, $password);
Mais évidemment, je m'y prends mal.
existe-t-il un moyen de transformer le tableau ... en quelque sorte en une liste à imprimer au stade de la requête bind_param
?
call_user_func_array()
!
call_user_func_array(array($stmt, "bind_param"), array_merge(array($type), $params));
devrait faire le travail
UPDATE: vous devez aussi changer votre tableau params:
$params = array(&$firstName, &$lastName, &$address, &$postcode, &$email, &$password);
comme mysqli_stmt::bind_param
attend le deuxième et les paramètres suivants par référence.
EDIT: Votre requête semble être fausse. Peut-être que vous avez moins de champs que de variables. Faire:
"INSERT INTO Users (field1, field2, field3, field4, field5, field6) VALUES (?, ?, ?, ?, ?, ?)"
où vous remplacez le nom des champs par les noms corrects
À partir de PHP 5.6, vous pouvez utiliser la décompression d'arguments comme alternative à call_user_func_array, et est souvent 3 à 4 fois plus rapide.
<?php
function foo ($a, $b) {
return $a + $b;
}
$func = 'foo';
$values = array(1, 2);
call_user_func_array($func, $values);
//returns 3
$func(...$values);
//returns 3
?>
Tiré de ici .
Donc, votre code devrait ressembler à quelque chose comme ça:
public function bind($query, $type, $params)
{
$this->query = $query;
$stmt = $this->mysqli->prepare($this->query);
$stmt->bind_param($type, ...$params);
$stmt->execute;
}
Vous obtenez probablement l'erreur "Appel à une fonction membre bind_param () sur un non-objet", car votre $ this-> mysqli-> prepare rencontre une sorte d'erreur . (Voir http: // php.net/manual/de/mysqli.prepare.php - il retourne FALSE en cas d'erreur, ce qui semble être le cas ici)
Après avoir résolu ce problème, essayez ceci à la place de votre appel de $ stmt-> bind_param:
call_user_func_array(array($stmt, 'bind_param'), array_merge($type, $params));
Aujourd'hui, j'ai moi-même effectué des recherches afin de créer une méthode plus courte d'utilisation de la déclaration prepare. La réponse @bwoebi est très utile mais ne fonctionne pas pour une quantité inconnue de paramètres, c’est donc un ajout à sa réponse.
Par exemple:
public function bind($query, $type, &...$params)
{
$this->query = $query;
$stmt = $this->mysqli->prepare($this->query);
call_user_func_array(array($stmt, "bind_param"), array_merge([$type], $params));
$stmt->execute();
}
en utilisant ce fil: PHP: argument de longueur variable liste par référence?
J'ai réussi à transmettre une quantité inconnue de paramètres à la fonction bind de la classe. i appelle ensuite la fonction bind param en utilisant call_user_func_array (...) avec une fusion de tableau de la variable $ type ... (doit être placée dans un tableau pour la fusion)
Maintenant, je peux faire appel à cette fonction avec $ email et $ mot de passe étant maintenant des références:
$myClass->bind($query, "ss", $email, $password);
Le moyen easiest serait apparemment de passer de mysqli à PDO
Il vous permettra de le faire comme vous le souhaitez, et même sans fonctions supplémentaires:
function registerUser($firstName, $lastName, $address, $postcode, $email, $password)
{
$sql = "INSERT INTO Users VALUES (NULL, ?, ?, ?, ?, ?, ?)";
$stmt = $this->db->prepare($sql);
$stmt->execute(func_get_args());
}
Il est important de noter que mysqli_stmt_bind_param()
requiert que les paramètres soient transmis par référence. Les paramètres de call_user_func_array()
doivent donc être une référence. Un exemple tiré du contexte de la classe:
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 );
}
}