Diferencia entre revisiones de «Plantilla:PHP/Mysqli»
De WikiEducator
(→¿Cuándo es necesario usar store_result()?) |
|||
| (5 revisiones intermedias por el mismo usuario no mostrado) | |||
| Línea 23: | Línea 23: | ||
;Para trabajar con una base de datos, siempre hemos de seguir una serie de acciones | ;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 | 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: | Si, por el motivo que fuera, no nos hemos podido conectar,generalmente: | ||
1.- Informaremos de ello | 1.- Informaremos de ello | ||
2.- Cerraremos la conexión | 2.- Cerraremos la conexión | ||
| − | + | ;3.- Realizaremos las operativas que necesitemos | |
Ejecutaremos sentencias SQL y recogeremos el resultado de la consulta | Ejecutaremos sentencias SQL y recogeremos el resultado de la consulta | ||
Generalmente informaremos de algo al usuario de la aplicación | Generalmente informaremos de algo al usuario de la aplicación | ||
| − | + | ;4.- Cerraremos la conexión | |
Un aspecto que puede pasar desapercibido, pero muy importante | Un aspecto que puede pasar desapercibido, pero muy importante | ||
}} | }} | ||
| Línea 169: | 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 359: | 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 634: | 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 654: | 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)

