10

Quisiera saber cual es la diferencia entre fetch y fetchall en php, por lo que vi por ahi fetch te devuelve un solo campo y fetchall todos los campos, pero utilizando PDO me parece que no importa cual utilize, total uso (PDO:: FETCH_ASSOC), pero igual quisiera saber la diferencia, gracias :)

plus
  • 768
  • 1
  • 5
  • 16
  • 4
    fetch() va a trabajar para devolver una fila de registros mientras que fetchAll() trabaja sobre todo el conjunto de registros; ahora si lo usas como fetchAll(PDO::FETCH_ASSOC) te transforma el conjunto de datos en un array de tipo asociativo –  Jul 27 '18 at 02:44

1 Answers1

14

Son dos cosas distintas mezcladas en la pregunta:

fetch

abre como un puntero listo para recorrer los datos uno por uno (generalmente mediante un ciclo while). Es el método recomendado cuando se esperan muchos datos, porque de ese modo no tendrás problemas de memoria.

Ejemplo de código:

$stmt = $pdo->prepare($sql);
$stmt->execute();
while ($fila = $stmt->fetch(PDO::FETCH_ASSOC)) {
  $datos []= $fila;
}

Aquí $datos será un array asociativo que se irá llenando con una fila cada vez que el puntero avanza dentro del while.

También, se puede imprimir el dato in situ si no se necesita para transportarlo a otro lugar:

while ($fila = $stmt->fetch(PDO::FETCH_ASSOC)) {
  echo $fila["nombre"]." ".$fila["apellido"].PHP_EOL;
}

fetchAll

te trae todos los datos de golpe, sin abrir ningún puntero, almacenándolos en un array. Se recomienda cuando no se esperan demasiados resultados que podrían provocar problemas de memoria al querer guardar de golpe en un array miles o millones de filas ¡! provenientes de un SELECT.

Ejemplo de código:

$resultado = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($resultado);

En este caso $resultado es un array asociativo con todos los datos de la consulta. Si se quieren leer las filas que hay en él, se puede implementar un bucle que recorra el array:

foreach ($resultado as $row){
    echo $row["nombre"]." ".$row["apellido"].PHP_EOL;
}

Es casi lo mismo que en fetch, sólo que aquí no estamos actuando sobre un recorrido de los datos a través de un puntero, sino sobre los datos ya almacenados en una variable. Si por ejemplo antes de esto nosotros cerramos el statemente, ya tenemos los datos en $resultado y podremos leerlos. En fetch si cerramos el statement no podremos leer los datos.


En cuanto a PDO::FETCH_ASSOC es sólo una forma de representación de los datos. Uno de los fetch_style que existen, el cual indica que quieres los resultados en forma de array asociativo donde la clave es el nombre de cada columna y el valor el dato perteneciente a esa columna. Lo puedes usar tanto con fetch como con fetchAll.

Cabe destacar que tanto para fetch como para fetchAll el estilo por defecto es PDO::FETCH_BOTH. Pero se puede establecer un estilo por defecto sea al objeto conexión mediante el método setAttribute, cambiando el valor de la constante PDO::ATTR_DEFAULT_FETCH_MODE; sea a un statement específico mediante el método setFechMode.

A. Cedano
  • 86,578
  • 19
  • 122
  • 221
  • 1
    Tendrías algún link de referencia sobre las velocidades y el uso de memoria entre `fetch()` y `fetchAll()`? De lo que he estado investigando en diferentes foros cada cual viene con su propio test y resultados diferentes en todos ellos. Por lo que he podido ver a menos que sean `unbuffered query:false` fetchAll es mas recomendable o al menos no hay diferencia de velocidad y la memoria en ambos casos es guardada por el PDO – CristianS9 Aug 02 '18 at 06:36
  • 1
    @CristianS9 no tengo nada sobre eso. Puedes ver algunas preguntas de SO en inglés: [Enlace1](https://stackoverflow.com/q/2770630/5587982) - [Enlace2](https://stackoverflow.com/a/13222923/5587982) - [Enlace3](https://stackoverflow.com/q/3328794/5587982) – A. Cedano Feb 01 '19 at 09:57