¿Cómo cambiar mysql a mysqli?

Resuelto JasonDavis asked hace 54 años • 12 respuestas

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;
}
?>
JasonDavis avatar Jan 01 '70 08:01 JasonDavis
Aceptado

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_connectserá reemplazado pormysqli_connect
  • mysql_errorserá reemplazado por mysqli_errory/o mysqli_connect_error, dependiendo del contexto
  • mysql_queryserá 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_dbuna 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_dbfunció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 ;-)
Pascal MARTIN avatar Sep 07 '2009 19:09 Pascal MARTIN

(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.

dhw avatar May 08 '2015 17:05 dhw

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, INSERTson UPDATElos 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_stringpara 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_errorsy 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_dbno tiene contrapartida. Utilice declaraciones preparadas o mysqli_queryen su lugar
  • mysql_drop_dbno tiene contrapartida. Utilice declaraciones preparadas o mysqli_queryen su lugar
  • mysql_db_name& mysql_list_dbsel soporte se ha abandonado a favor de SQLSHOW DATABASES
  • mysql_list_tablesEl soporte se ha abandonado a favor de SQL.SHOW TABLES FROM dbname
  • mysql_list_fieldsEl soporte se ha abandonado a favor de SQL.SHOW COLUMNS FROM sometable
  • mysql_db_query-> use mysqli_select_db()luego la consulta o especifique el nombre de la base de datos en la consulta
  • mysql_fetch_field($result, 5)-> el segundo parámetro (desplazamiento) no está presente en mysqli_fetch_field. Puede utilizar mysqli_fetch_field_directteniendo 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_processesha sido removido. Si necesita ID de hilo, usemysqli_thread_id
  • mysql_pconnectha sido reemplazado con mysqli_connect()el p:prefijo de host
  • mysql_result-> utilizar mysqli_data_seek()junto con mysqli_field_seek()ymysqli_fetch_field()
  • mysql_tablenameEl soporte se ha abandonado a favor de SQL.SHOW TABLES
  • mysql_unbuffered_queryha sido removido. Consulte este artículo para obtener más información sobre consultas con y sin búfer.
Dharman avatar Jul 11 '2019 22:07 Dharman

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.

  1. Todos " mysql_select_db( " con " mysqli_select_db($con, "
  2. Todo " mysql_query( " con " mysqli_query($con, " y
  3. Todo " mysql_ " con " mysqli_ ".

Esto me funciona siempre

Aduragbemi Ogundijo avatar May 20 '2017 02:05 Aduragbemi Ogundijo