sentencias - prepared statement php
Cómo enlazar mysqli bind_param argumentos dinámicamente en PHP? (4)
He estado aprendiendo a usar declaraciones preparadas y encuadernadas para mis consultas sql, y hasta ahora he llegado a la conclusión de que funciona bien, pero no es dinámico cuando se trata de múltiples parámetros o cuando no se necesita ningún parámetro,
public function get_result($sql,$parameter)
{
# create a prepared statement
$stmt = $this->mysqli->prepare($sql);
# bind parameters for markers
# but this is not dynamic enough...
$stmt->bind_param("s", $parameter);
# execute query
$stmt->execute();
# these lines of code below return one dimentional array, similar to mysqli::fetch_assoc()
$meta = $stmt->result_metadata();
while ($field = $meta->fetch_field()) {
$var = $field->name;
$$var = null;
$parameters[$field->name] = &$$var;
}
call_user_func_array(array($stmt, ''bind_result''), $parameters);
while($stmt->fetch())
{
return $parameters;
//print_r($parameters);
}
# close statement
$stmt->close();
}
Así es como llamo a las clases de objetos,
$mysqli = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME);
$output = new search($mysqli);
A veces no necesito pasar ningún parámetro,
$sql = "
SELECT *
FROM root_contacts_cfm
";
print_r($output->get_result($sql));
A veces solo necesito un parámetro,
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
ORDER BY cnt_id DESC
";
print_r($output->get_result($sql,''1''));
A veces solo necesito más de un parámetro,
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
AND root_contacts_cfm.cnt_firstname = ?
ORDER BY cnt_id DESC
";
print_r($output->get_result($sql,''1'',''Tk''));
Por lo tanto, creo que esta línea no es lo suficientemente dinámica para las tareas dinámicas anteriores,
$stmt->bind_param("s", $parameter);
Para construir un bind_param dinámicamente, he encontrado esto en otras publicaciones en línea.
call_user_func_array(array(&$stmt, ''bind_params''), $array_of_params);
Intenté modificar algún código de php.net pero no estoy llegando a ninguna parte,
if (strnatcmp(phpversion(),''5.3'') >= 0) //Reference is required for PHP 5.3+
{
$refs = array();
foreach($arr as $key => $value)
$array_of_param[$key] = &$arr[$key];
call_user_func_array(array(&$stmt, ''bind_params''), $array_of_params);
}
¿Por qué? ¿Alguna idea de cómo puedo hacer que funcione?
O tal vez hay mejores soluciones?
O tal vez hay mejores soluciones?
Esta respuesta realmente no te ayuda mucho, pero deberías considerar seriamente cambiar a PDO desde mysqli.
La razón principal de esto es porque PDO hace lo que estás tratando de hacer en mysqli con funciones integradas. Además de tener un enlace de param manual , el método de ejecución puede tomar una matriz de argumentos en su lugar.
PDO es fácil de extender, y agregar métodos de conveniencia para buscar-todo-y-devolver en lugar de hacer el baile de preparar-ejecutar es muy fácil.
Encontré una buena clase de mysqli, puede manejar parámetros dinámicos y es fácil de usar
https://github.com/ajillion/PHP-MySQLi-Database-Class
Puede referir el código fuente cómo genera dinámicamente la consulta
https://github.com/ajillion/PHP-MySQLi-Database-Class/blob/master/MysqliDb.php
Usando PHP 5.6 puedes hacer esto fácil con la ayuda de desempacar el operador ( ...$var
) y usar get_result () de bind_result ()
public function get_result($sql,$types = null,$params = null) {
$stmt = $this->mysqli->prepare($sql);
$stmt->bind_param($types, ...$params);
if(!$stmt->execute()) return false;
return $stmt->get_result();
}
Ejemplo:
$mysqli = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME);
$output = new search($mysqli);
$sql = "SELECT * FROM root_contacts_cfm WHERE root_contacts_cfm.cnt_id = ?
AND root_contacts_cfm.cnt_firstname = ?
ORDER BY cnt_id DESC";
$res = $output->get_result($sql, ''ss'',array(''1'',''Tk''));
while($row = res->fetch_assoc()){
echo $row[''fieldName''] .''<br>'';
}
encontró la respuesta para mysqli:
public function get_result($sql,$types = null,$params = null)
{
# create a prepared statement
$stmt = $this->mysqli->prepare($sql);
# bind parameters for markers
# but this is not dynamic enough...
//$stmt->bind_param("s", $parameter);
if($types&&$params)
{
$bind_names[] = $types;
for ($i=0; $i<count($params);$i++)
{
$bind_name = ''bind'' . $i;
$$bind_name = $params[$i];
$bind_names[] = &$$bind_name;
}
$return = call_user_func_array(array($stmt,''bind_param''),$bind_names);
}
# execute query
$stmt->execute();
# these lines of code below return one dimentional array, similar to mysqli::fetch_assoc()
$meta = $stmt->result_metadata();
while ($field = $meta->fetch_field()) {
$var = $field->name;
$$var = null;
$parameters[$field->name] = &$$var;
}
call_user_func_array(array($stmt, ''bind_result''), $parameters);
while($stmt->fetch())
{
return $parameters;
//print_r($parameters);
}
# the commented lines below will return values but not arrays
# bind result variables
//$stmt->bind_result($id);
# fetch value
//$stmt->fetch();
# return the value
//return $id;
# close statement
$stmt->close();
}
entonces:
$mysqli = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME);
$output = new search($mysqli);
$sql = "
SELECT *
FROM root_contacts_cfm
ORDER BY cnt_id DESC
";
print_r($output->get_result($sql));
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
ORDER BY cnt_id DESC
";
print_r($output->get_result($sql,''s'',array(''1'')));
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
AND root_contacts_cfm.cnt_firstname = ?
ORDER BY cnt_id DESC
";
print_r($output->get_result($sql, ''ss'',array(''1'',''Tk'')));
mysqli es tan cojo cuando se trata de esto. ¡Creo que debería migrar a PDO!