Diferencia entre revisiones de «Plantilla:PHP/Mysqli»
De WikiEducator
(→Mysql y su extensión mysqli para php) |
(→¿Cuándo es necesario usar store_result()?) |
||
| (8 revisiones intermedias por el mismo usuario no mostrado) | |||
| Línea 9: | Línea 9: | ||
<div class="slide"> | <div class="slide"> | ||
| − | ;Uso básico de | + | ;Uso básico de un recurso de tipo '''''mysqli''''' |
*Recordamos que para crear una nueva instancia de una clase usamos el operador '''''new''''' | *Recordamos que para crear una nueva instancia de una clase usamos el operador '''''new''''' | ||
<source lang=php> | <source lang=php> | ||
| Línea 19: | Línea 19: | ||
</source> | </source> | ||
</div> | </div> | ||
| + | |||
| + | {{MRM_Puntos clave|Title=Acciones básicas que hemos de aprender| | ||
| + | ;Para trabajar con una base de datos, siempre hemos de seguir una serie de acciones | ||
| + | |||
| + | ;1.- Concetarnos a la base de datos | ||
| + | Esto será crear una instancia de un objeto de conexión | ||
| + | ;2.- Verificar que la conexión se ha realizado | ||
| + | Si, por el motivo que fuera, no nos hemos podido conectar,generalmente: | ||
| + | 1.- Informaremos de ello | ||
| + | 2.- Cerraremos la conexión | ||
| + | ;3.- Realizaremos las operativas que necesitemos | ||
| + | Ejecutaremos sentencias SQL y recogeremos el resultado de la consulta | ||
| + | Generalmente informaremos de algo al usuario de la aplicación | ||
| + | ;4.- Cerraremos la conexión | ||
| + | Un aspecto que puede pasar desapercibido, pero muy importante | ||
| + | }} | ||
| Línea 34: | Línea 50: | ||
<div class="slide"> | <div class="slide"> | ||
;Extensión Mysqli | ;Extensión Mysqli | ||
| − | *El constructor de la clase puede recibir hasta 5 parámetros, de los cuales 4 se suelen usar con bastante frecuencia | + | *El '''''constructor''''' de la clase puede recibir hasta '''5 parámetros''', de los cuales '''''4''''' se suelen usar con bastante frecuencia |
#'''''$host''''' nombre o ip del equipo (null o localhost, identificaría el equipo actual).i | #'''''$host''''' nombre o ip del equipo (null o localhost, identificaría el equipo actual).i | ||
#'''''$usario''''' es el usuario de la base de datos | #'''''$usario''''' es el usuario de la base de datos | ||
| Línea 53: | Línea 69: | ||
$miConexion = new mysqli ($host,$usuario,$pass,$nombreBD); | $miConexion = new mysqli ($host,$usuario,$pass,$nombreBD); | ||
if ($miConexion==null) | if ($miConexion==null) | ||
| − | echo"No se ha podido crear el objeto"; | + | echo"No se ha podido crear el objeto. |
| + | Seguramente no tiene instalada la extensión mysqli. | ||
| + | Prueba a instalar apt install php-mysql "; | ||
else | else | ||
echo "Objeto creado"; | echo "Objeto creado"; | ||
| Línea 59: | Línea 77: | ||
</div> | </div> | ||
<div class="slide"> | <div class="slide"> | ||
| + | {{Nota|Pruena a ver el contenido del objeto con '''''var_dump''''', así podrás observar los atributos que tenemos disponibles. Son todos muy intuitivos y los iremos viendo a lo largo de este tema.}} | ||
| + | <source lang=php> | ||
| + | var_dump($miConexion); | ||
| + | </source> | ||
| + | |||
;mysqli(...) | ;mysqli(...) | ||
*Esta función retorna el recurso de la conexión. | *Esta función retorna el recurso de la conexión. | ||
| Línea 64: | Línea 87: | ||
'''Un recurso a diferencia de una clase no se puede serializar para pasar entre scripts.''' | '''Un recurso a diferencia de una clase no se puede serializar para pasar entre scripts.''' | ||
}} | }} | ||
| − | *Para gestionar los errores debemos de usar | + | *Para gestionar los errores de la conexión, debemos de usar los atributos: |
| + | # '''''connect_errno''''': Número o códiog del error que se ha producido en la conexión. 0 implica que no hay error. | ||
| + | # '''''connect_error''''':Descripción del error en forma de string. "" (cadena vacía) es la descripción cuando no ha habido error en la conexión. | ||
| + | de la clase '''''mysqli'''''. | ||
*El echo de que se pueda instanciar o el objeto de la clase, no implica que se haya realizado la conexión. | *El echo de que se pueda instanciar o el objeto de la clase, no implica que se haya realizado la conexión. | ||
*Este atributo aporta información sobre el error o contiene null si no se ha producido ninguno. | *Este atributo aporta información sobre el error o contiene null si no se ha producido ninguno. | ||
| Línea 143: | Línea 169: | ||
<div class="slide"> | <div class="slide"> | ||
| − | ==== | + | ====Ejecutando sentencias SQL: DML (insert, delete, update, select)==== |
*En SQL sabemos que tenmos tres tipos de lenguajes DDL, DML, DCL | *En SQL sabemos que tenmos tres tipos de lenguajes DDL, DML, DCL | ||
*Nos vamos a centrar en el DML, Leguane de maniputación de datos | *Nos vamos a centrar en el DML, Leguane de maniputación de datos | ||
| Línea 206: | Línea 232: | ||
'''''Qué pasa si en nombre de la tienda es por ejemplo Technology's house''''' | '''''Qué pasa si en nombre de la tienda es por ejemplo Technology's house''''' | ||
*Habría que escapar ese carácter}} | *Habría que escapar ese carácter}} | ||
| + | {{MRM_Actividad|Title=Inserción de datos| | ||
| + | *Realiza una aplicación para insertar datos en una tabla llamada usuarios | ||
| + | *Insertaremos '''''Nombre''''', '''''Password''''' y edad | ||
| + | *Verificaremos la insercción accediendo a la base de datos con phpmyadmin | ||
| + | *El password que esté cifrada | ||
| + | }} | ||
====Escapar caracteres==== | ====Escapar caracteres==== | ||
| Línea 327: | Línea 359: | ||
*En el segundo caso nos retornará un booleano y para leer los datos deberemos usar o '''''store_result''''' o '''''use_result''''' según veamos a continuación. | *En el segundo caso nos retornará un booleano y para leer los datos deberemos usar o '''''store_result''''' o '''''use_result''''' según veamos a continuación. | ||
</div> | </div> | ||
| + | *El método '''''query''''' con una sentencia de tipo '''''select''''' como parámetro, nos retorna un objeto de la clase mysqli_result. Esta clase (recurso) implemente la interfaz '''''Traversable''''', lo que le hace iterable en los datos que contiene. | ||
| + | *Esta clase contiene el resultado de la consulta como un conjunto de filas, pero no lo tiene como un atributo visible, si no como parte de los métodos que tenemos disponibles para obtenerlo (los metodos fetch_xxxx) | ||
<div class="slide"> | <div class="slide"> | ||
| Línea 602: | Línea 636: | ||
<div class="slide"> | <div class="slide"> | ||
| − | ====Consultas preparadas que retornan valores==== | + | ==== Consultas preparadas que retornan valores ==== |
| − | *En caso de que la consulta preparada retorne valores se | + | * En caso de que la consulta preparada retorne valores, se pueden recuperar de dos formas: |
| − | * | + | ** Usando el método '''bind_result()''' y '''fetch()''' |
| − | * | + | ** Usando el método '''get_result()''' (requiere que PHP tenga activado el controlador '''mysqlnd''') |
| − | * | + | |
| + | * Ambas formas permiten recorrer los resultados de una consulta SELECT preparada. | ||
| + | * A continuación, veremos ambas formas con ejemplos. | ||
| + | |||
</div> | </div> | ||
<div class="slide"> | <div class="slide"> | ||
;Consultas preparadas que generan valores | ;Consultas preparadas que generan valores | ||
| + | *En caso de que la consulta preparada retorne valores se recogen con el método '''bind_result''' | ||
| + | * Este método recibirá variables en los que se almacenarán los valores de las columnas resultado de la sentencia | ||
| + | *Posteriormente, para recorre el conjunto de valores, usamos el método '''fetch()''' | ||
| + | Vemos el siguiente ejemplo | ||
<source lang=php> | <source lang=php> | ||
$consulta = $conexion->stmt_init(); | $consulta = $conexion->stmt_init(); | ||
| Línea 622: | Línea 663: | ||
</source> | </source> | ||
</div> | </div> | ||
| + | |||
<div class="slide"> | <div class="slide"> | ||
| + | * Este método necesita declarar de antemano una variable por cada columna del resultado. | ||
| + | * Para recorrer las filas usamos un bucle con '''fetch()'''. | ||
| + | * Es útil cuando conocemos con certeza la estructura de la tabla o del resultado. | ||
| + | |||
| − | |||
| − | |||
{{MRM_Actividad| | {{MRM_Actividad| | ||
| − | *Modifica el ejercicio anterior usando consultas parametrizadas | + | * Modifica el ejercicio anterior usando consultas parametrizadas |
| + | * Por ejemplo: que el número mínimo de unidades se reciba como parámetro | ||
| + | * En caso de que no coincidas, se lanzará una excepción. | ||
}} | }} | ||
| + | ''' Puede ser necesario, ejectuar el método store_result previo a otras acciones''': | ||
| + | <div class="slide"> | ||
| + | |||
| + | ==== ¿Cuándo es necesario usar store_result()? ==== | ||
| + | |||
| + | * El método '''store_result()''' no siempre es obligatorio, pero sí es recomendable o necesario en algunas situaciones específicas. | ||
| + | * Su función es almacenar todos los resultados devueltos por una consulta SELECT preparada en memoria. | ||
| + | |||
| + | ;¿Cuándo es necesario o recomendable? | ||
| + | |||
| + | * Cuando queremos conocer el número de filas devueltas con '''$stmt->num_rows'''. | ||
| + | **Sin store_result(), num_rows devuelve 0.** | ||
| + | |||
| + | * Cuando vamos a extraer los datos más tarde, no justo después de ejecutar la consulta. | ||
| + | **store_result() mantiene los datos en memoria y disponibles.** | ||
| + | |||
| + | * Cuando queremos recorrer los resultados más de una vez. | ||
| + | **Normalmente solo puedes hacer un fetch(), pero con store_result() puedes volver atrás.** | ||
| + | |||
| + | * Cuando no vamos a extraer todas las filas. | ||
| + | **Si no usamos store_result() y dejamos resultados pendientes, la conexión puede quedar bloqueada.** | ||
| + | |||
| + | ;¿Cuándo no es necesario? | ||
| + | |||
| + | * Cuando vamos a extraer todas las filas inmediatamente, una tras otra con '''fetch()'''. | ||
| + | * Cuando no necesitamos contar filas ni reutilizar los resultados después. | ||
| + | |||
</div> | </div> | ||
| + | <div class="slide"> | ||
| + | ;Resumen | ||
| + | |||
| + | {| class="wikitable" | ||
| + | ! Caso de uso !! ¿Es necesario store_result()? | ||
| + | |- | ||
| + | | Usar '''$stmt->num_rows''' || Sí | ||
| + | |- | ||
| + | | Hacer fetch() inmediatamente || No | ||
| + | |- | ||
| + | | Extraer solo algunas filas || Sí | ||
| + | |- | ||
| + | | Usar los datos más tarde || Sí | ||
| + | |- | ||
| + | | Liberar la conexión tras ejecutar SELECT || Sí | ||
| + | |} | ||
| + | |||
| + | {{MRM_Actividad| | ||
| + | * Si tienes dudas, puedes usar '''store_result()''' sin problema: funciona bien y evita errores futuros. | ||
| + | * Pero ten en cuenta que consume más memoria, especialmente si hay muchas filas. | ||
| + | }} | ||
| + | </div> | ||
| + | |||
| + | |||
| + | |||
| + | <div class="slide"> | ||
| + | ;Recuperar valores con get_result | ||
| + | <source lang=php> | ||
| + | $consulta = $conexion->prepare('SELECT producto, unidades FROM stock WHERE unidades < ?'); | ||
| + | $consulta->bind_param("i", $limite); | ||
| + | $limite = 2; | ||
| + | $consulta->execute(); | ||
| + | |||
| + | $resultado = $consulta->get_result(); // obtenemos el mysqli_result | ||
| + | |||
| + | while ($fila = $resultado->fetch_assoc()) { | ||
| + | echo "<p>Producto {$fila['producto']}: {$fila['unidades']} unidades.</p>"; | ||
| + | } | ||
| + | |||
| + | $consulta->close(); | ||
| + | $conexion->close(); | ||
| + | </source> | ||
| + | </div> | ||
| + | |||
| + | <div class="slide"> | ||
| + | * Este método es más flexible y cómodo para trabajar con arrays asociativos. | ||
| + | * Es útil cuando queremos mostrar tablas completas o cuando el número de columnas puede cambiar. | ||
| + | * No requiere declarar una variable por cada columna. | ||
| + | * Solo funciona si PHP fue compilado con el controlador '''mysqlnd''' (MySQL Native Driver). | ||
| + | |||
| + | ;Comparativa entre bind_result y get_result | ||
| + | |||
| + | {| class="wikitable" | ||
| + | ! Método !! Ventajas !! Limitaciones | ||
| + | |- | ||
| + | | '''bind_result()''' || Más eficiente en memoria y compatible universalmente || Requiere declarar variables y conocer la estructura de la consulta | ||
| + | |- | ||
| + | | '''get_result()''' || Muy fácil de usar y compatible con arrays asociativos || Solo funciona si el servidor PHP usa mysqlnd | ||
| + | |} | ||
| + | |||
| + | </div> | ||
| + | <div class="slide"> | ||
| + | * Aquí hay un enlace para una información completa sobre consultas preparadas: | ||
| + | http://php.net/manual/es/class.mysqli-stmt.php | ||
| + | |||
| + | |||
<div class="slide"> | <div class="slide"> | ||
{{MRM_Actividad|Title=Práctica de tienda| | {{MRM_Actividad|Title=Práctica de tienda| | ||
Última revisión de 17:04 9 abr 2025
Esto será crear una instancia de un objeto de conexión
Si, por el motivo que fuera, no nos hemos podido conectar,generalmente: 1.- Informaremos de ello 2.- Cerraremos la conexión
Ejecutaremos sentencias SQL y recogeremos el resultado de la consulta Generalmente informaremos de algo al usuario de la aplicación
Un aspecto que puede pasar desapercibido, pero muy importante
|
- El método query con una sentencia de tipo select como parámetro, nos retorna un objeto de la clase mysqli_result. Esta clase (recurso) implemente la interfaz Traversable, lo que le hace iterable en los datos que contiene.
- Esta clase contiene el resultado de la consulta como un conjunto de filas, pero no lo tiene como un atributo visible, si no como parte de los métodos que tenemos disponibles para obtenerlo (los metodos fetch_xxxx)

