Estructuras de control: bucle foreach

El bucle foreach

El bucle foreach es un tipo especial de bucle que permite recorrer estructuras que contienen varios elementos (como matrices, recursos u objetos) sin necesidad de preocuparse por el número de elementos.

Problemas al recorrer matrices con el bucle for

En caso de que una matriz tenga índices que sean números enteros correlativos, las matrices se pueden recorrer fácilmente con bucles for, como muestra el siguiente ejemplo:

Ejemplo de bucle for correcto (1)

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)
</pre>
<p>a</p>
<p>bb</p>
<p>ccc</p>
<p>dddd</p>
<p>Final</p>

Puede ver la ejecución paso a paso de este programa utilizando los iconos de avance y retroceso situados abajo a la derecha.

Siguiente

Ejemplo de bucle for correcto (1) - Paso 1

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>

Se ejecuta la primera instrucción del programa.

En este caso, se crea la matriz $matriz.

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 2

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>

A continuación se abre la etiqueta <pre>.

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 3

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)

A continuación se imprimen los valores de la matriz $matriz.

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 4

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)
</pre>

A continuación se cierra la etiqueta </pre>.

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 5

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)
</pre>

A continuación se ejecuta el bucle. El primer paso es dar el valor inicial a la variable de control.

En este caso, la variable de control es $i y toma el valor 0.

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 6

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)
</pre>

A continuación se comprueba que la condición de continuación se cumple.

En este caso, $i es inferior a 4 (vale 0), así que se pasa a ejecutar las instrucciones del bloque de sentencias.

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 7

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)
</pre>
<p>a</p>

A continuación se ejecutan las instrucciones del bloque.

En este caso, se imprime el texto <p>a</p> ya que $i tiene el valor 0 y $matriz[0] tiene el valor "a".

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 8

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)
</pre>
<p>a</p>

A continuación se ejecuta de nuevo la instrucción de paso.

En este caso, la variable $i aumenta una unidad, por lo que ahora vale 1.

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 9

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)
</pre>
<p>a</p>

A continuación se comprueba de nuevo que la condición de continuación se cumple.

En este caso, $i es inferior a 4 (vale 1), así que se pasa a ejecutar las instrucciones del bloque de sentencias.

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 10

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)
</pre>
<p>a</p>
<p>bb</p>

A continuación se ejecutan de nuevo las instrucciones del bloque.

En este caso, se imprime el texto <p>bb</p> ya que $i tiene el valor 1 y $matriz[1] tiene el valor "bb".

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 11

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)
</pre>
<p>a</p>
<p>bb</p>

A continuación se ejecuta de nuevo la instrucción de paso.

En este caso, la variable $i aumenta una unidad, por lo que ahora vale 2.

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 12

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)
</pre>
<p>a</p>
<p>bb</p>

A continuación se comprueba de nuevo que la condición de continuación se cumple.

En este caso, $i es inferior a 4 (vale 2), así que se pasa a ejecutar las instrucciones del bloque de sentencias.

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 13

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)
</pre>
<p>a</p>
<p>bb</p>
<p>ccc</p>

A continuación se ejecutan de nuevo las instrucciones del bloque.

En este caso, se imprime el texto <p>ccc</p> ya que $i tiene el valor 2 y $matriz[2] tiene el valor "ccc".

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 14

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)
</pre>
<p>a</p>
<p>bb</p>
<p>ccc</p>

A continuación se ejecuta de nuevo la instrucción de paso.

En este caso, la variable $i aumenta una unidad, por lo que ahora vale 3.

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 15

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)
</pre>
<p>a</p>
<p>bb</p>
<p>ccc</p>

A continuación se comprueba de nuevo que la condición de continuación se cumple.

En este caso, $i es inferior a 4 (vale 3), así que se pasa a ejecutar las instrucciones del bloque de sentencias.

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 16

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)
</pre>
<p>a</p>
<p>bb</p>
<p>ccc</p>
<p>dddd</p>

A continuación se ejecutan de nuevo las instrucciones del bloque.

En este caso, se imprime el texto <p>dddd</p> ya que $i tiene el valor 3 y $matriz[3] tiene el valor "dddd".

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 17

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)
</pre>
<p>a</p>
<p>bb</p>
<p>ccc</p>
<p>dddd</p>

A continuación se ejecuta de nuevo la instrucción de paso.

En este caso, la variable $i aumenta una unidad, por lo que ahora vale 4.

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 18

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)
</pre>
<p>a</p>
<p>bb</p>
<p>ccc</p>
<p>dddd</p>

A continuación se comprueba de nuevo que la condición de continuación se cumple.

En este caso, $i ya no es inferior a 4 (vale 4), así que no se ejecutan las instrucciones del bloque de sentencias y el bucle se termina.

Anterior Siguiente

Ejemplo de bucle for correcto (1) - Paso 19

<?php
$matriz = ["a", "bb", "ccc", "ddd"];
print "<pre>\n";
print_r($matriz);
print "</pre>\n";
for ($i = 0; $i < 4; $i++) {
    print "<p>$matriz[$i]</p>\n";
}
print "<p>Final</p>\n";
?>
<pre>
Array
(
    [0] => a
    [1] => bb
    [2] => ccc
    [3] => dddd
)
</pre>
<p>a</p>
<p>bb</p>
<p>ccc</p>
<p>dddd</p>
<p>Final</p>

Una vez terminado el bucle, se ejecuta la instrucción que sigue al bucle.

En este caso, imprime el párrafo final.

Anterior

Pero como las matrices de PHP son matrices asociativas y los índices de las matrices no tienen por qué ser números enteros correlativos, nos podemos encontrar con problemas. Por ejemplo, podemos hacer involuntariamente referencia a un término inexistente o algunos términos pueden resultar inaccesibles.

Sintaxis del bucle foreach

La sintaxis del bucle foreach puede ser una de las siguientes:

foreach ($matriz as $valor) {
    bloque_de_sentencias
}
foreach ($matriz as $indice => $valor) {
    bloque_de_sentencias
}

La ejecución de esta estructura de control es la siguiente:

El bucle se ejecuta tantas veces como elementos tiene la matriz. En cada iteración, las variables $indice y $valor van tomando los valores de los índices y de la matriz para ese índice.

Si sólo se necesitan los valores almacenados en la matriz se puede utilizar tanto la primera como la segunda forma. Si se necesitan tanto los índices como los valores se debe utilizar la segunda forma. Si sólo se necesitan los índices también se debe utilizar la segunda forma.

Diagrama de flujo

El diagrama de flujo siguiente muestra la ejecución de un bucle foreach ...:

DIAGRAMA DE FLUJO: BUCLE FOREACH Haga clic en los botones de avance y retroceso para ver la ejecución paso a paso El programa llega al bucle foreach. INICIO Evalúa si la matriz tiene elementos ... ¿Hay elementos en la matriz? Si no hay ningún elemento, termina el bucle foreach. false FIN Si hay algún elemento, asigna el primer elemento a la variable auxiliar ... true Asigna primer valor ... ejecuta el bloque de instrucciones ... Bloque ... y evalúa si hay más elementos. ¿Quedan elementos en la matriz? Si los hay, asigna el siguiente valor a la variable auxiliar ... true Asigna valor siguiente ... vuelve a ejecutar el bloque ... ... y vuelve a evaluar si hay más elementos. ¿Quedan elementos en la matriz? Si no los hay, termina el bucle foreach. false FIN El programa llega al bucle foreach. INICIO Evalúa si la matriz tiene elementos ... ¿Hay elementos en la matriz? Si no hay ningún elemento, termina el bucle foreach. false FIN Si hay algún elemento, asigna el primer elemento a la variable auxiliar ... true Asigna primer valor ... ejecuta el bloque de instrucciones ... Bloque ... y evalúa si hay más elementos. ¿Quedan elementos en la matriz? Si los hay, asigna el siguiente valor a la variable auxiliar ... true Asigna valor siguiente ... vuelve a ejecutar el bloque ... Bloque ... y vuelve a evaluar si hay más elementos. ¿Quedan elementos en la matriz? Si no los hay, termina el bucle foreach. false FIN

Ejemplos de bucles foreach ...

Matrices

Consultas a bases de datos

Los bucles foreach se utilizan habitualmente para tratar los resultados de las consultas a bases de datos, como se comenta en el apartado Gestión de los registros devueltos por la consulta de la lección PHP Data Objects (PDO).