Nueva pregunta

Pregunta:

Fecha: 11-01-2016 11:47:20 (En Español)

Migrar funciones PHP MySQL (Deprecated) a MySQLi[Resuelta]

Hola a todos, me encuentro en la tarea de migrar un desarrollo realizado con las funciones MySQL (actualmente deprecadas por PHP) a MySQLi....

El motivo de mi post es solicitarles recomendaciones para realizar esta migración lo más ordenada y limpia posible, no se si alguien de la comunidad ya ha pasado por esto y pueda darme consejo.

Muchas gracias a todos de antemano.

Saludos!
Etiquetas: Funcionalidades obsoletas (Deprecated) - MySQL - PHP - PHP MySQLi - Pregunta Votos: 3 - Respuestas: 7 - Vistas: 48 Compartir en: Google Facebook Twitter LinkedIn Link
 

Respuestas:

  • Fecha: 11-01-2016 15:50:21 Hola
    Encontre un articulo en la red que trata el tema que has planteado.

    Explica como convertir de MySQL a MySQLi
    Migrar ext PHP/mysql a MySQLi

    Y encontre este video aunque no lo he visto, desconozco su calidad.

    Cap 2 Hot Pack: Pasar de MySQL a MySQLi




    Espero que te sirva para orientarte un poco.

    Si encuentro algo mas lo publico.

    Saludos
      Votos: 4 - Link respuesta
     
  • Fecha: 11-01-2016 15:53:14 Asi es como yo realizo mis consultas con mysqli
    https://gist.github.com/ZeusAFK/024614b55a87ddb1bf96

    Función para el manejo de llamadas a procedimientos almacenados en mysql que limpia correctamente los result sets teniendo en cuenta si esta activo o no mysql native driver para evitar los problemas mas comunes al utilizar procedimientos almacenados como "Commands out of sync; you can't run this command now" o "Packets out of order. Expected 1 r…

    <?php
    /*
      Parametros
      
      $query = llamada a procedimiento almacenado, puede ser un string o un objeto mysqli_stmt, en caso de ser un string se prepara la nueva consulta y se cierra al finalizar el metodo, de ser un objeto mysqli_stmt simplemente se utiliza y no se cierra al finalizar
      $types = Lista de tipo de dato de los parametros recibidos por el procedimiento almacenado, si no hay parametros utilizar '' o false
      $params = Parametros para el procedimiento almacenado, si no hay parametros utilizar array() o false
      $results = Array con lista de valores devueltos por el procedimiento almacenado para crear el arreglo $results utilizado por el callback, si no hay resultados utilizar array() o false, nota: igualmente al pasar false si la consulta devuelve resultados estos se armaran en un array automaticamente con el nombre de las columnas devuelvas en el resultado
      $callback = Function que recibe la variable results con los resultados del procedimiento almacenado, se ejecuta por cada resultset devuelto, si no es necesario un callback utilizar function($results){} o false
      $mysqli = Objeto mysqli_connection, conexion a utilizar para realizar la consulta
    */
    	function ExecutePreparedCallableStatement($query, $types = false, $params = false, $results = false, $callback = false, $mysqli = false){
    		// Verificamos si no se especifico una conexion mysql
    		if(!$mysqli){
    			// Aqui necesitan actualizar por la forma en que accederan a una conexion mysql por defecto, en mi caso una variable global $mysqli = new mysqli(...)
    			global $mysqli;
    		}
    		
    		// Si el primer argumento es un mysqli_stmt utilizamos esa consulta preparada, caso contrario preparamos una nueva consulta
    		$new_prepared_statement = true;
    		
    		if($query instanceof mysqli_stmt){
    			$stmt = $query;
    			$new_prepared_statement = false;
    		}else if(!($stmt = $mysqli->prepare($query))){
    			echo $mysqli->error;
    		}
    		
    		// Verificamos primero si se recibio parametros para la consulta
    		if($types && $params){
    			// Si el parametro no es un array lo convertimos en uno
    			if(!is_array($params)){
    				$params = array($params);
    			}
    			
    			// Cambiamos los parametros de manera que se puedan pasar por referencia, esto es necesario para mysqli::bind_param
    			$referencedParams = array();
    			foreach($params as $k => $param){
    				$referencesParams[$k] = &$params[$k];
    			}
    			
    			// Si recibimos parametros llamamos a mysqli::bind_result combinando la lista de tipo de datos con los parametros
    			if(sizeof($params) > 0){
    				call_user_func_array(array($stmt, "bind_param"), array_merge(array($types), $referencesParams));
    			}
    		}
    		
    		// Ejecutamos la consulta, TODO: Controlar algun posible error si la consulta no se ejecuta correctamente
    		$success = $stmt->execute();
    		
    		if($success){
    			// Si no se especifico la lista de resultados los obtenemos de los metadatos del resultado
    			if(!$results){
    				$result = $stmt->result_metadata();
    				$info_fields = $result->fetch_fields();
    				$results = array();
    				foreach ($info_fields as $field){
    					$results[] = $field->name;
    				}
    			}
    		}
    		
    		if($results){
    			// Preparamos el contenedor para recibir los resultados del procedimiento almacenado en base a la lista de resultados recibida por parametro
    			$formattedResults = array();
    			$valuesContainer = array();
    			foreach($results as $k => $value){
    				$valuesContainer[$k] = null;
    				$formattedResults[$value] = &$valuesContainer[$k];
    			}
    		
    			// Si se especifico que se recibiria resultados del procedimiento llamamos a mysqli::bind_result para enlazar los resultados
    			if(sizeof($results) > 0){
    				call_user_func_array(array($stmt, "bind_result"), $formattedResults);
    			}
    		}
    		
    		// Verificamos si se esta utilizando mysql native driver ya que de ser asi la forma de limpiar los result sets de estado del procedimiento almacenado es diferente y suele causar problemas
    		if(function_exists('mysqli_fetch_all')){
    		  // Se esta utilizando mysql native driver
    			do {
    				$stmt->store_result();
    				while($stmt->fetch()){
    				  // Ejecutamos el callback con los resultados del procedimiento almacenado como parametro
    					$callback && $callback($formattedResults);
    				}
    				// Limpiamos los result sets para poder seguir realizando consultas con la misma conexion a mysql
    			} while ($stmt->more_results() && $stmt->next_result());
    		}else{
    		  // No se esta utilizando mysql native driver
    			$stmt->store_result();
    			while($stmt->fetch()){
    			  // Ejecutamos el callback con los resultados del procedimiento almacenado como parametro
    				$callback && $callback($formattedResults);
    			}
    			// Limpiamos los result sets para poder seguir realizando consultas con la misma conexion a mysql
    			$stmt->free_result();
    			// Si la consulta preparada se creo en esta funcion entonces la cerramos
    			if($new_prepared_statement){
    				$stmt->close();
    			}
    			while ($mysqli->more_results()){
    				$mysqli->next_result();
    				$result = $mysqli->use_result();
    				if ($result instanceof mysqli_result) {
    					$result->free();
    				}
    			}
    		}
    		return $success;
    	}
    	
    	// Ejemplo: 
    	
    	$mysqli = new mysqli($config['DB']['HOST'], $config['DB']['USR'], $config['DB']['PSW'], $config['DB']['NAME'], $config['DB']['PORT']);
    	
    	$pictures = array();
    	$params = array($product['id'], $color);
    	if(ExecutePreparedCallableStatement('CALL getProductPictures(?,?)', 'is', $params, false, function($results) use (&$pictures){
    		$picture = array();
    		foreach($results as $key => $value) $picture[$key] = $value;
    		$pictures[] = $picture;
    	})){
    		// Consulta ejecutada exitosamente, ahora podemos trabajar con los datos obtenidos
    		$product['pictures'] = $pictures;
    	}
    	
    	
    	// Ejemplo 2:
    	$getPackagesItemsByPackageQuery = reset($CONFIG['DB'])['CONN']->prepare('CALL getPackagesItemsByPackage(?)');
    
    	foreach($packages as &$package){
    		$items = array();
    		ExecutePreparedCallableStatement($getPackagesItemsByPackageQuery, 'i', $package['id'], false, function($results) use (&$items){
    			$item = array();
    			foreach($results as $key => $value) $item[$key] = $value;
    			$items[] = $item;
    		});
    		$package['items'] = $items;
    	}
    
    	$service['packages'] = $packages;
    	
    	// Ejemplo 3:
    	return ExecutePreparedCallableStatement('UPDATE product SET `status` = 0 WHERE id = ?', 'i', $product['id']);
    ?>
    
      Votos: 4 - Link respuesta
     
  • Fecha: 12-01-2016 08:21:58 Muchas gracias por la info, agradecería también los consejos de algún usuarios que se haya visto en esta situación, problemas encontrados, particularidades, etc.

    Las funciones a migrar son:

    Funciones de MySQL:
    mysql_affected_rows — Obtiene el número de filas afectadas en la anterior operación de MySQL
    mysql_client_encoding — Devuelve el nombre del conjunto de caracteres
    mysql_close — Cerrar una conexión de MySQL
    mysql_connect — Abre una conexión al servidor MySQL
    mysql_create_db — Crea una base de datos MySQL
    mysql_data_seek — Mueve el puntero de resultados interno
    mysql_db_name — Recupera el nombre de la base de datos desde una llamada a mysql_list_dbs
    mysql_db_query — Selecciona una base de datos y ejecuta una consulta sobre la misma
    mysql_drop_db — Elimina (DROP) una base de datos MySQL
    mysql_errno — Devuelve el valor numérico del mensaje de error de la última operación MySQL
    mysql_error — Devuelve el texto del mensaje de error de la operación MySQL anterior
    mysql_escape_string — Escapa una cadena para ser usada en mysql_query
    mysql_fetch_array — Recupera una fila de resultados como un array asociativo, un array numérico o como ambos
    mysql_fetch_assoc — Recupera una fila de resultados como un array asociativo
    mysql_fetch_field — Obtiene la información de una columna de un resultado y la devuelve como un objeto
    mysql_fetch_lengths — Obtiene la longitud de cada salida en un resultado
    mysql_fetch_object — Recupera una fila de resultados como un objeto
    mysql_fetch_row — Obtiene una fila de resultados como un array numérico
    mysql_field_flags — Obtiene las banderas asociadas al campo especificado de un resultado
    mysql_field_len — Devuelve la longitud del campo especificado
    mysql_field_name — Obtiene el nombre del campo especificado de un resultado
    mysql_field_seek — Establece el puntero del resultado en un índice de campo específicado
    mysql_field_table — Obtiene el nombre de la tabla en la que está el campo especificado
    mysql_field_type — Obtiene el tipo del campo especificado de un resultado
    mysql_free_result — Libera la memoria del resultado
    mysql_get_client_info — Obtiene información del cliente MySQL
    mysql_get_host_info — Obtener información del anfitrión de MySQL
    mysql_get_proto_info — Obtener información del protocolo MySQL
    mysql_get_server_info — Obtiene información del servidor MySQL
    mysql_info — Obtiene información sobre la consulta más reciente
    mysql_insert_id — Obtiene el ID generado en la última consulta
    mysql_list_dbs — Lista las bases de datos disponibles en un servidor MySQL
    mysql_list_fields — Lista los campos de una tabla de MySQL
    mysql_list_processes — Lista los procesos de MySQL
    mysql_list_tables — Enumerar las tablas de una base de datos MySQL
    mysql_num_fields — Obtiene el número de campos de un resultado
    mysql_num_rows — Obtener el número de filas de un conjunto de resultados
    mysql_pconnect — Abre una conexión persistente a un servidor MySQL
    mysql_ping — Efectuar un chequeo de respuesta (ping) sobre una conexión al servidor o reconectarse si no hay conexión
    mysql_query — Enviar una consulta MySQL
    mysql_real_escape_string — Escapa caracteres especiales en una cadena para su uso en una sentencia SQL
    mysql_result — Obtener datos de resultado
    mysql_select_db — Seleccionar una base de datos MySQL
    mysql_set_charset — Establece el conjunto de caracteres del cliente
    mysql_stat — Obtiene el estado actual del sistema
    mysql_tablename — Obtiene el nombre de la tabla de un campo
    mysql_thread_id — Devuelve el ID del hilo actual
    mysql_unbuffered_query — Envía una consulta SQL a MySQL, sin recuperar ni almacenar en búfer las filas de resultados

    Muchas gracias a todos!
      Votos: 4 - Link respuesta
     
  • Fecha: 12-01-2016 08:55:05 Pues para trabajar con MySQLi esa función que hice es lo único que utilizo y me ha servido para todo lo que he necesitado en un sistema PHP de mas de 80000 lineas de código que trabaja bastante con base de datos sin problemas.   Votos: 4 - Link respuesta
     
  • Fecha: 13-01-2016 04:00:58 Hola Jorge, muchas gracias por tu aporte, pero mi pregunta tiene como objetivo obtener respuestas sobre experiencias en la migración de las funciones de MySQL (deprecated) a MySQLi.

    Por lo general (cuando es mi decisión) utilizo PDO, pero este no es el caso, ya que me estan solicitando migrar a MySQLi.

    Muchas gracias a todos por sus respuestas.
      Votos: 2 - Link respuesta
     
  • Fecha: 13-01-2016 05:14:01 Pues me pregunto como planeas hacer tu migración, quieres sobreescribir todas las funciones que usaste de mysql por las de mysqli?? eso no es mas complicado que modificar tu código? :)   Votos: 0 - Link respuesta
     
  • Fecha: 03-09-2016 00:49:09 Ha pasado algo de tiempo, pero recién ahora me di a la tarea de hacer el cambio de versión de PHP y como consecuencia no he podido utilizar más las funciones deprecadas de MySQL, por lo tanto no me quedo otra que aplicar una solución. Comparto aquí la solución a mi caso y doy por cerrada la pregunta.

    Las funciones utilizadas en mi código eran las siguientes:
    mysql_connect — Abre una conexión al servidor MySQL
    mysql_close — Cerrar una conexión de MySQL
    mysql_error — Devuelve el texto del mensaje de error de la operación MySQL anterior
    mysql_select_db — Seleccionar una base de datos MySQL
    mysql_query — Enviar una consulta MySQL
    mysql_fetch_array — Recupera una fila de resultados como un array asociativo, un array numérico o como ambos

    y la solución fue remplazarlas por su versión "mysqli" salvando algunos detalles de implementación distintos:

    mysql_connect remplazo directo por mysqli_connect.
    mysql_close remplazo directo por mysqli_close.
    mysql_error remplazo por mysqli_error pero agregando el parametro $link (conexión).
    mysql_select_db remplazo por mysqli_select_db pero invirtiendo los parametros (antes era $dbname, $link, y ahora es $link, $dbname).
    mysql_query remplazo por mysqli_query pero agregando como primer parametro el $link (conexión) y luego la query.
    mysql_fetch_array remplazo directo por mysqli_fetch_array.

    Saludos y muchas gracias a todos!
      Votos: 2 - Link respuesta
     
Para participar activamente de la comunidad primero debes autenticarte, ingresa al sistema.Iniciar Sesión
 
frjcbbae garagebible.com