Lección 4: Bucles

Un bucle, o loop, se utiliza para repetir un conjunto de instrucciones un serie de ocasiones. Ello quiere decir que puedes realizar la misma tarea tantas veces cono necesites: una, ninguna, x veces; pero no infinitas porque sino nunca llegaría a terminar de generarse el HTML. Cada repetición se denomina iteración.

Nada mejor que un ejemplo para probar su potencial. Si ejecutas el siguiente código…

<html>
    <body>
        <h1>¿Cuantos años tienes?</h1>
        <select>
            <?php foreach (range(1, 10) as $num): ?>
            <option value="<?php echo $num; ?>"><?php echo $num . ' años'; ?></option>
            <?php endforeach; ?>
        </select>
    </body>
</html>

… te generará este HTML.

<html>
    <body>
        <h1>¿Cuantos años tienes?</h1>
        <select>
            <option value="1">1 años</option>
            <option value="2">2 años</option>
            <option value="3">3 años</option>
            <option value="4">4 años</option>
            <option value="5">5 años</option>
            <option value="6">6 años</option>
            <option value="7">7 años</option>
            <option value="8">8 años</option>
            <option value="9">9 años</option>
            <option value="10">10 años</option>
        </select>
    </body>
</html

Lo más probable es que el código sea indescifrable para tus ojos y estés buscando la ventana más cercana para saltar. ¡Alto! Aún no me interesa que comprendas su significado, pero si su potencial. A pesar de su sencillez, con 3 líneas de PHP, hemos generado 10 de HTML y porque nos hemos parado. Ahora ponte en el caso que tu jefe te pida una tabla con los años del 1890 al 2000. Si haces un loop similar al ejemplo lo tiene antes de que la máquina de café termine de hacerte un cortado. ¡Super útil! ¿Puedes imaginar sitios web que usen loops para simplificar el trabajo? Te propongo que mires: tiendas, blogs, periódicos, redes sociales…

Dentro de PHP existen 4 tipos de bucles:

  • foreach
  • for
  • while
  • do-while

Todos son diferentes estrategias a la hora de decidir el número de veces que se va a iterar, en el fondo hacen lo mismo. Veamos uno por uno como funcionan.

foreach

Es la forma más sencilla de iterar un array.

$animalesFantasticos = ['fénix', 'dragón', 'grifo', 'pegaso', 'cerbero'];
foreach ($animalesFantasticos as $animal) {
    echo $animal . ' ';
} 
// fénix dragón grifo pegaso cerbero

En caso de que necesitemos la key, existe otra forma para utilizarlo.

$animalesFantasticos = ['fénix', 'dragón', 'grifo', 'pegaso', 'cerbero'];
foreach ($animalesFantasticos as $posicion => $animal) {
    echo "El animal $animal ocupa la posición $posicion \n";
}
// El animal fénix ocupa la posición 0 
// El animal dragón ocupa la posición 1 
// El animal grifo ocupa la posición 2 
// El animal pegaso ocupa la posición 3 
// El animal cerbero ocupa la posición 4 

3-1

Respecto a range() es una función nativa de PHP que genera un array de elementos. Admite 2 o 3 parámetros.

range($inicio, $fin, $pasos);
var_dump(range(10, 15));
/*
array(6) {
  [0] =>
  int(10)
  [1] =>
  int(11)
  [2] =>
  int(12)
  [3] =>
  int(13)
  [4] =>
  int(14)
  [5] =>
  int(15)
}
*/
var_dump(range(0, 100, 20));
/*
array(6) {
  [0] =>
  int(0)
  [1] =>
  int(20)
  [2] =>
  int(40)
  [3] =>
  int(60)
  [4] =>
  int(80)
  [5] =>
  int(100)
}
*/

Para insertar un bucle dentro de un HTML tienes 2 formas. En el ejemplo esta escrito con foreach pero es válido cualquier loop o condicional.

Sintaxis clásica.

<html>
    <body>
        <?php foreach (range(1, 5) as $num) { ?>
        <p><?php echo $num; ?></p>
        <?php } ?>
    </body>
</html>

Sintaxis alternativa.

<html>
    <body>
        <?php foreach (range(1, 5) as $num): ?>
        <p><?php echo $num; ?></p>
        <?php endforeach; ?>
    </body>
</html>

Ambos dan el mismo resultado.

<html>
    <body>
        <p>1</p>
        <p>2</p>
        <p>3</p>
        <p>4</p>
        <p>5</p>
    </body>
</html>

3-2

Recorrer arrays multidimensionales

Para poder leer un array con más de una dimensión, tendremos que realizar bucles anidados. O un bucle dentro de otro bucle.

Tomamos de partida un array, de 2 dimensiones, que vimos en la lección anterior.

$zara = [
    123 => [
      'nombre' => 'Camisa a cuadros',
      'precio' => 29.95,
      'sexo' => 'Hombre'
    ],
    234 => [
      'nombre' => 'Falda manga',
      'precio' => 19.95,
      'sexo' => 'Mujer'
    ],
    345 => [
      'nombre' => 'Bolso minúsculo',
      'precio' => 50,
      'sexo' => 'Mujer'
    ]
];

Si yo quisiera mostrar toda la información de los productos.

foreach ($zara as $producto) {
    var_dump($producto);
}

/*
array(3) {
  'nombre' =>
  string(16) "Camisa a cuadros"
  'precio' =>
  double(29.95)
  'sexo' =>
  string(6) "Hombre"
}

array(3) {
  'nombre' =>
  string(11) "Falda manga"
  'precio' =>
  double(19.95)
  'sexo' =>
  string(5) "Mujer"
}

array(3) {
  'nombre' =>
  string(16) "Bolso minúsculo"
  'precio' =>
  int(50)
  'sexo' =>
  string(5) "Mujer"
}
*/

Ha iterado 3 veces, y en cada ocasión me ha devuelvo un array. Es lo que hay contenido dentro del primer array, otros arrayss. Entonces debo recorrer cada uno con otro foreach.

foreach ($zara as $producto) {
    foreach ($producto as $elemento) {
        echo "$elemento \n";
    }
}

// Camisa a cuadros
// 29.95
// Hombre
// Falda manga
// 19.95
// Mujer
// Bolso minúsculo
// 50
// Mujer

Y ahora sí lo tengo.

Los bucles anidados se pueden realizar con cualquier tipo de loop. Te recomiendo que trabajes siempre que puedas con foreach ya que será más difícil que acabes teniendo un bucle infinito.

3-3

for

El loop más complejo y similar a otros lenguajes (C, Java, Javascript…).

for (variable inicio; condicional; incremento) {
    ...
}
for ($i = 0; $i < 10; $i++) {
    echo "$i \n";
}
// 0
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9

$i++ es equivalente a $i += 1 o $i = $i + 1. Básicamente incrementa en 1 la variable. Además dispones de su antítesis: $i--.

3-4

while

Es el bucle más sencillo y peligroso. Debes prestar mucha atención para que se acabe en algún momento.

while (condicional) {
    ...
}
$i = 1;
while ($i < 10) {
    echo $i++;
}
// 123456789

do-while

Se comporta igual que while, salvo que se compromete a ejecutarse al menos una vez. Independientemente de si se cumple la condicional. El secreto radica en que primero se ejecuta las instrucciones y a continuación se evalúa el condicional.

do {
    ...
} while (condicional)
$i = 1;
do {
    echo $i++;
} while ($i < 10);
// 123456789
$i = 20;
do {
    echo $i++;
} while ($i < 10);
// 20