php - mysqli_stmt - Bind Param con una matriz de parámetros
mysqli_stmt_bind_param integer (5)
Obtiene el error "Es muy probable que llame a una función miembro bind_param () en un no objeto, porque su $ this-> mysqli-> prepare encuentra algún tipo de error. (vea http://php.net/manual/de/mysqli.prepare.php - devuelve FALSE en caso de error, que parece ser el caso aquí)
Después de resolver el problema, intente esto en lugar de llamar a $ stmt-> bind_param:
call_user_func_array(array($stmt, ''bind_param''), array_merge($type, $params));
Tengo una función que hace esto:
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);
}
Lo cual envía a mi clase de base de datos, que hace esto:
public function bind($query, $type, $params)
{
$this->query = $query;
$stmt = $this->mysqli->prepare($this->query);
$stmt->bind_param($type, $param);
$stmt->execute;
}
El problema es que esto no funciona.
Lo que esperaba hacer era tomar la lista de $params
y hacer que los incluyera después del $type
, para que la consulta se asemejara a:
$stmt->bind_param(''ssssss'', $firstName, $lastName, $address, $postcode, $email, $password);
Pero obviamente lo estoy haciendo mal.
¿Hay alguna manera de hacer que la matriz ... se transforme por así decirlo, en una lista para imprimir en la etapa de consulta bind_param
?
call_user_func_array()
!
call_user_func_array(array($stmt, "bind_param"), array_merge(array($type), $params));
debería hacer el trabajo
ACTUALIZACIÓN : también debe cambiar su matriz params:
$params = array(&$firstName, &$lastName, &$address, &$postcode, &$email, &$password);
como mysqli_stmt::bind_param
espera el segundo y los siguientes parámetros por referencia.
EDITAR: su consulta parece estar equivocada. Tal vez tengas menos campos que variables allí. Hacer:
"INSERT INTO Users (field1, field2, field3, field4, field5, field6) VALUES (?, ?, ?, ?, ?, ?)"
donde reemplaza el nombre de los campos por los nombres correctos
Es importante tener en cuenta que mysqli_stmt_bind_param()
requiere que los parámetros se pasen por referencia, por lo que los parámetros para call_user_func_array()
deben ser una referencia. Un ejemplo tomado del contexto de clase:
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 );
}
}
A partir de PHP 5.6, puede utilizar el desempaquetado de argumentos como alternativa a call_user_func_array, y suele ser de 3 a 4 veces más rápido.
$func = ''foo'';
$values = array(1, 2);
call_user_func_array($func, $values);
//returns 3
$func(...$values);
//returns 3
?>
Tomado de aquí .
Por lo tanto, su código debería verse más o menos así:
public function bind($query, $type, $params)
{
$this->query = $query;
$stmt = $this->mysqli->prepare($this->query);
$stmt->bind_param($type, ...$params);
$stmt->execute;
}
La manera más fácil sería aparentemente cambiar de mysqli a PDO
Le permitirá hacerlo de la manera que desee, e incluso sin funciones adicionales:
function registerUser($firstName, $lastName, $address, $postcode, $email, $password)
{
$sql = "INSERT INTO Users VALUES (NULL, ?, ?, ?, ?, ?, ?)";
$stmt = $this->db->prepare($sql);
$stmt->execute(func_get_args());
}