¿Cómo cambiar mysql a mysqli?
Según el siguiente código que uso para mysql normal, ¿cómo podría convertirlo para usar mysqli?
¿ Es tan simple como cambiar mysql_query($sql);
a mysqli_query($sql);
?
<?PHP
//in my header file that is included on every page I have this
$DB["dbName"] = "emails";
$DB["host"] = "localhost";
$DB["user"] = "root";
$DB["pass"] = "";
$link = mysql_connect($DB['host'], $DB['user'], $DB['pass']) or die("<center>An Internal Error has Occured. Please report following error to the webmaster.<br><br>".mysql_error()."'</center>");
mysql_select_db($DB['dbName']);
// end header connection part
// function from a functions file that I run a mysql query through in any page.
function executeQuery($sql) {
$result = mysql_query($sql);
if (mysql_error()) {
$error = '<BR><center><font size="+1" face="arial" color="red">An Internal Error has Occured.<BR> The error has been recorded for review</font></center><br>';
if ($_SESSION['auto_id'] == 1) {
$sql_formatted = highlight_string(stripslashes($sql), true);
$error .= '<b>The MySQL Syntax Used</b><br>' . $sql_formatted . '<br><br><b>The MySQL Error Returned</b><br>' . mysql_error();
}
die($error);
}
return $result;
}
// example query ran on anypage of the site using executeQuery function
$sql='SELECT auto_id FROM friend_reg_user WHERE auto_id=' .$info['auto_id'];
$result_member=executequery($sql);
if($line_member=mysql_fetch_array($result_member)){
extract($line_member);
} else {
header("location: index.php");
exit;
}
?>
Lo primero que debe hacer probablemente sería reemplazar cada mysql_*
llamada a función con su equivalente mysqli_*
, al menos si está dispuesto a utilizar la API de procedimiento, lo cual sería la forma más fácil, considerando que ya tiene algo de código basado en la API de MySQL, que es de carácter procesal.
Para ayudar con eso, el Resumen de funciones de la extensión MySQLi es definitivamente algo que resultará útil.
Por ejemplo:
mysql_connect
será reemplazado pormysqli_connect
mysql_error
será reemplazado pormysqli_error
y/omysqli_connect_error
, dependiendo del contextomysql_query
será reemplazado pormysqli_query
- etcétera
Nota: Para algunas funciones, es posible que necesite verificar los parámetros cuidadosamente: tal vez haya algunas diferencias aquí y allá, pero no tantas, diría: tanto mysql como mysqli se basan en la misma biblioteca ( libmysql; al menos para PHP <= 5.2)
Por ejemplo:
- con mysql, tienes que usar el
mysql_select_db
una vez conectado, para indicar en qué base de datos quieres hacer tus consultas - mysqli, por otro lado, le permite especificar el nombre de la base de datos como el cuarto parámetro de
mysqli_connect
. - Aún así, también hay una
mysqli_select_db
función que puedes utilizar, si lo prefieres.
Una vez que haya terminado con eso, intente ejecutar la nueva versión de su script... Y verifique si todo funciona; si no... Es hora de buscar errores ;-)
(Me doy cuenta de que esto es antiguo, pero todavía aparece...)
Si reemplaza mysql_*
con mysqli_*
, tenga en cuenta que una gran cantidad de mysqli_*
funciones necesitan que se pase el enlace de la base de datos.
P.ej:
mysql_query($query)
se convierte
mysqli_query($link, $query)
Es decir, se requieren muchas comprobaciones.
La guía definitiva para actualizar mysql_*
funciones a la API MySQLi
El motivo de la nueva extensión mysqli fue aprovechar las nuevas características que se encuentran en los sistemas MySQL versiones 4.1.3 y posteriores. Al cambiar su código existente mysql_*
a la API mysqli, debe aprovechar estas mejoras; de lo contrario, sus esfuerzos de actualización podrían ser en vano.
La extensión mysqli tiene una serie de beneficios, siendo las mejoras clave con respecto a la extensión mysql:
- Interfaz orientada a objetos
- Soporte para declaraciones preparadas
- Capacidades de depuración mejoradas
Al actualizar de mysql_*
funciones a MySQLi, es importante tener en cuenta estas características, así como algunos cambios en la forma en que se debe utilizar esta API.
1. Interfaz orientada a objetos versus funciones procedimentales.
La nueva interfaz orientada a objetos de mysqli es una gran mejora con respecto a las funciones anteriores y puede hacer que su código sea más limpio y menos susceptible a errores tipográficos. También existe la versión de procedimiento de esta API, pero se desaconseja su uso ya que genera un código menos legible, que es más propenso a errores.
Para abrir una nueva conexión a la base de datos con MySQLi, necesita crear una nueva instancia de la clase MySQLi.
$mysqli = new \mysqli($host, $user, $password, $dbName);
$mysqli->set_charset('utf8mb4');
Usando un estilo procesal se vería así:
$mysqli = mysqli_connect($host, $user, $password, $dbName);
mysqli_set_charset($mysqli, 'utf8mb4');
Tenga en cuenta que solo los primeros 3 parámetros son iguales que en mysql_connect
. El mismo código en la antigua API sería:
$link = mysql_connect($host, $user, $password);
mysql_select_db($dbName, $link);
mysql_query('SET NAMES utf8');
Si su código PHP dependía de una conexión implícita con parámetros predeterminados definidos en php.ini, ahora debe abrir la conexión MySQLi pasando los parámetros en su código y luego proporcionar el enlace de conexión a todas las funciones de procedimiento o usar el estilo OOP.
Para más información vea el artículo: Cómo conectarse correctamente usando mysqli
2. Soporte para declaraciones preparadas
Este es un grande. MySQL ha agregado soporte para declaraciones preparadas nativas en MySQL 4.1 (2004). Las declaraciones preparadas son la mejor manera de evitar la inyección de SQL . Era lógico que se agregara soporte para declaraciones preparadas nativas a PHP. Las declaraciones preparadas deben usarse siempre que sea necesario pasar datos junto con la declaración SQL (es decir WHERE
, INSERT
son UPDATE
los casos de uso habituales).
La antigua API de MySQL tenía una función para escapar de las cadenas utilizadas en SQL llamada mysql_real_escape_string
, pero nunca fue pensada para proteger contra inyecciones de SQL y, naturalmente, no debería usarse para ese propósito.
La nueva API MySQLi ofrece una función sustituta mysqli_real_escape_string
para la compatibilidad con versiones anteriores, que sufre los mismos problemas que la anterior y, por lo tanto, no debe usarse a menos que no haya declaraciones preparadas disponibles.
La antigua forma mysql_*:
$login = mysql_real_escape_string($_POST['login']);
$result = mysql_query("SELECT * FROM users WHERE user='$login'");
La forma de declaración preparada:
$stmt = $mysqli->prepare('SELECT * FROM users WHERE user=?');
$stmt->bind_param('s', $_POST['login']);
$stmt->execute();
$result = $stmt->get_result();
Las declaraciones preparadas en MySQLi pueden parecer un poco desagradables para los principiantes. Si está iniciando un nuevo proyecto, entonces podría ser una buena idea decidir utilizar la API PDO más potente y sencilla.
3. Capacidades de depuración mejoradas
Algunos desarrolladores de PHP de la vieja escuela están acostumbrados a comprobar manualmente los errores de SQL y mostrarlos directamente en el navegador como medio de depuración. Sin embargo, esta práctica resultó no sólo engorrosa, sino también un riesgo para la seguridad. Afortunadamente, MySQLi ha mejorado las capacidades de informe de errores.
MySQLi puede informar cualquier error que encuentre como excepciones de PHP. Las excepciones de PHP aparecerán en el script y, si no se controlan, lo finalizarán instantáneamente, lo que significa que nunca se ejecutará ninguna declaración posterior a la errónea. La excepción desencadenará un error fatal de PHP y se comportará como cualquier error desencadenado desde el núcleo de PHP que obedezca la configuración display_errors
y log_errors
. Para habilitar las excepciones de MySQLi, use la línea mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT)
e insértela justo antes de abrir la conexión a la base de datos.
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new \mysqli($host, $user, $password, $dbName);
$mysqli->set_charset('utf8mb4');
Si estaba acostumbrado a escribir código como:
$result = mysql_query('SELECT * WHERE 1=1');
if (!$result) {
die('Invalid query: ' . mysql_error());
}
o
$result = mysql_query('SELECT * WHERE 1=1') or die(mysql_error());
ya no es necesario die()
en su código.
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new \mysqli($host, $user, $password, $dbName);
$mysqli->set_charset('utf8mb4');
$result = $mysqli->query('SELECT * FROM non_existent_table');
// The following line will never be executed due to the mysqli_sql_exception being thrown above
foreach ($result as $row) {
// ...
}
Si por alguna razón no puedes usar excepciones, MySQLi tiene funciones equivalentes para la recuperación de errores. Puede utilizarlo mysqli_connect_error()
para comprobar si hay errores de conexión y mysqli_error($mysqli)
cualquier otro error. Preste atención al argumento obligatorio mysqli_error($mysqli)
o, alternativamente, apéguese al estilo y uso de la programación orientada a objetos $mysqli->error
.
$result = $mysqli->query('SELECT * FROM non_existent_table') or trigger_error($mysqli->error, E_USER_ERROR);
Consulte estas publicaciones para obtener más explicaciones:
mysqli o morir, ¿tiene que morir?
¿Cómo obtener información de error de MySQLi en diferentes entornos?
4. Otros cambios
Desafortunadamente, no todas las funciones mysql_*
tienen su contraparte en MySQLi solo con una "i" agregada en el nombre y el enlace de conexión como primer parámetro. Aquí hay una lista de algunos de ellos:
mysql_client_encoding()
ha sido reemplazado pormysqli_character_set_name($mysqli)
mysql_create_db
no tiene contrapartida. Utilice declaraciones preparadas omysqli_query
en su lugarmysql_drop_db
no tiene contrapartida. Utilice declaraciones preparadas omysqli_query
en su lugarmysql_db_name
&mysql_list_dbs
el soporte se ha abandonado a favor de SQLSHOW DATABASES
mysql_list_tables
El soporte se ha abandonado a favor de SQL.SHOW TABLES FROM dbname
mysql_list_fields
El soporte se ha abandonado a favor de SQL.SHOW COLUMNS FROM sometable
mysql_db_query
-> usemysqli_select_db()
luego la consulta o especifique el nombre de la base de datos en la consultamysql_fetch_field($result, 5)
-> el segundo parámetro (desplazamiento) no está presente enmysqli_fetch_field
. Puede utilizarmysqli_fetch_field_direct
teniendo en cuenta los diferentes resultados obtenidos.mysql_field_flags
,mysql_field_len
,mysql_field_name
,mysql_field_table
&mysql_field_type
-> ha sido reemplazado pormysqli_fetch_field_direct
mysql_list_processes
ha sido removido. Si necesita ID de hilo, usemysqli_thread_id
mysql_pconnect
ha sido reemplazado conmysqli_connect()
elp:
prefijo de hostmysql_result
-> utilizarmysqli_data_seek()
junto conmysqli_field_seek()
ymysqli_fetch_field()
mysql_tablename
El soporte se ha abandonado a favor de SQL.SHOW TABLES
mysql_unbuffered_query
ha sido removido. Consulte este artículo para obtener más información sobre consultas con y sin búfer.
La forma más fácil en la que siempre manejo esto es donde
$con = mysqli_connect($serverName,$dbusername,$dbpassword);
Reemplazo de 3 pasos en el siguiente orden.
- Todos " mysql_select_db( " con " mysqli_select_db($con, "
- Todo " mysql_query( " con " mysqli_query($con, " y
- Todo " mysql_ " con " mysqli_ ".
Esto me funciona siempre