Lección 12 de 75 15 min de lectura

Bucles: while, do-while, for, foreach

Los bucles permiten repetir código múltiples veces. PHP ofrece cuatro tipos de bucles, cada uno optimizado para diferentes situaciones. Dominarlos es esencial para trabajar con datos y automatizar tareas repetitivas.

Bucle while

Ejecuta código mientras una condición sea verdadera. La condición se evalúa antes de cada iteración.

PHP
<?php

// Sintaxis básica
$contador = 1;

while ($contador <= 5) {
    echo "Iteración $contador\n";
    $contador++;
}

// Salida:
// Iteración 1
// Iteración 2
// Iteración 3
// Iteración 4
// Iteración 5

// Ejemplo práctico: leer hasta encontrar un valor
$numeros = [4, 7, 2, 9, 5, 1];
$indice = 0;

while ($indice < count($numeros) && $numeros[$indice] !== 9) {
    echo $numeros[$indice] . " ";
    $indice++;
}
// Salida: 4 7 2
Cuidado con los bucles infinitos

Asegúrate de que la condición eventualmente sea falsa. Si olvidas incrementar el contador o modificar la condición, el bucle nunca terminará y tu script se bloqueará.

Bucle do-while

Similar a while, pero la condición se evalúa después de cada iteración. Esto garantiza que el código se ejecute al menos una vez.

PHP
<?php

// Sintaxis básica
$contador = 1;

do {
    echo "Iteración $contador\n";
    $contador++;
} while ($contador <= 5);

// Diferencia clave con while:
$valor = 10;

// Este while NO ejecuta nada (condición falsa desde el inicio)
while ($valor < 5) {
    echo 'Nunca se imprime';
}

// Este do-while ejecuta UNA vez aunque la condición sea falsa
do {
    echo "Se imprime una vez\n";
} while ($valor < 5);

// Ejemplo práctico: pedir entrada hasta que sea válida
$intentos = 0;
$maxIntentos = 3;

do {
    $intentos++;
    $entrada = obtenerEntrada(); // Función hipotética
    $valido = validar($entrada);
} while (!$valido && $intentos < $maxIntentos);

Bucle for

El bucle más estructurado. Ideal cuando sabes exactamente cuántas veces quieres iterar. Combina inicialización, condición e incremento en una línea.

PHP
<?php

// Sintaxis: for (inicialización; condición; incremento)
for ($i = 0; $i < 5; $i++) {
    echo "Iteración $i\n";
}

// Salida: 0, 1, 2, 3, 4

// Contar hacia atrás
for ($i = 10; $i >= 0; $i--) {
    echo "$i... ";
}
echo '¡Despegue!';

// Incrementos diferentes
for ($i = 0; $i <= 20; $i += 5) {
    echo "$i "; // 0 5 10 15 20
}

// Múltiples variables
for ($i = 0, $j = 10; $i < $j; $i++, $j--) {
    echo "i=$i, j=$j\n";
}
// i=0, j=10
// i=1, j=9
// ...
// i=4, j=6

// Iterar sobre un array (aunque foreach es mejor para esto)
$frutas = ['manzana', 'pera', 'naranja'];

for ($i = 0; $i < count($frutas); $i++) {
    echo $frutas[$i] . "\n";
}
Optimización

Cuando uses count() en la condición, considera guardarlo en una variable. Así evitas recalcularlo en cada iteración: for ($i = 0, $len = count($arr); $i < $len; $i++)

Bucle foreach

Diseñado específicamente para recorrer arrays y objetos iterables. Es el bucle más usado en PHP moderno.

PHP
<?php

$frutas = ['manzana', 'pera', 'naranja'];

// Solo valores
foreach ($frutas as $fruta) {
    echo $fruta . "\n";
}

// Con índice/clave
foreach ($frutas as $indice => $fruta) {
    echo "$indice: $fruta\n";
}
// 0: manzana
// 1: pera
// 2: naranja

// Arrays asociativos
$persona = [
    'nombre' => 'Ana',
    'edad' => 28,
    'ciudad' => 'Madrid'
];

foreach ($persona as $clave => $valor) {
    echo "$clave: $valor\n";
}
// nombre: Ana
// edad: 28
// ciudad: Madrid

// Arrays multidimensionales
$usuarios = [
    ['nombre' => 'Ana', 'rol' => 'admin'],
    ['nombre' => 'Luis', 'rol' => 'editor'],
    ['nombre' => 'María', 'rol' => 'usuario'],
];

foreach ($usuarios as $usuario) {
    echo "{$usuario['nombre']} es {$usuario['rol']}\n";
}

Modificar valores con foreach

Por defecto, foreach trabaja con copias de los valores. Para modificar el array original, usa referencias con &:

PHP
<?php

$numeros = [1, 2, 3, 4, 5];

// Esto NO modifica el array original
foreach ($numeros as $numero) {
    $numero *= 2; // Solo modifica la copia
}
print_r($numeros); // [1, 2, 3, 4, 5] - Sin cambios

// Con referencia (&) SÍ modifica el original
foreach ($numeros as &$numero) {
    $numero *= 2;
}
unset($numero); // ¡Importante! Eliminar la referencia después

print_r($numeros); // [2, 4, 6, 8, 10]
Siempre haz unset después de usar referencias

Si no haces unset($variable) después de un foreach con referencia, la variable sigue apuntando al último elemento. Esto puede causar bugs difíciles de detectar si reutilizas esa variable.

Cuándo usar cada bucle

PHP
<?php

// ✓ USA FOREACH para recorrer arrays u objetos
$productos = obtenerProductos();
foreach ($productos as $producto) {
    mostrar($producto);
}

// ✓ USA FOR cuando necesitas el índice o un número fijo de iteraciones
for ($i = 0; $i < 10; $i++) {
    echo "Línea $i\n";
}

// ✓ USA WHILE cuando no sabes cuántas iteraciones necesitas
while ($linea = fgets($archivo)) {
    procesar($linea);
}

// ✓ USA DO-WHILE cuando necesitas al menos una ejecución
do {
    $respuesta = pedirConfirmacion();
} while ($respuesta !== 'si' && $respuesta !== 'no');

Sintaxis alternativa para templates

Como otras estructuras de control, los bucles tienen sintaxis alternativa:

PHP
<?php $productos = [
    ['nombre' => 'Laptop', 'precio' => 999],
    ['nombre' => 'Mouse', 'precio' => 29],
    ['nombre' => 'Teclado', 'precio' => 79],
]; ?>

<ul class="lista-productos">
    <?php foreach ($productos as $producto): ?>
        <li>
            <strong><?= htmlspecialchars($producto['nombre']) ?></strong>
            <span>$<?= $producto['precio'] ?></span>
        </li>
    <?php endforeach; ?>
</ul>

<!-- También funciona con for y while -->
<?php for ($i = 1; $i <= 5; $i++): ?>
    <p>Párrafo <?= $i ?></p>
<?php endfor; ?>

Ejemplos prácticos

PHP
<?php

// Sumar todos los elementos de un array
$numeros = [10, 20, 30, 40, 50];
$suma = 0;

foreach ($numeros as $numero) {
    $suma += $numero;
}
echo "Suma: $suma"; // 150

// Filtrar elementos
$edades = [15, 22, 17, 30, 16, 25];
$mayores = [];

foreach ($edades as $edad) {
    if ($edad >= 18) {
        $mayores[] = $edad;
    }
}
print_r($mayores); // [22, 30, 25]

// Buscar un elemento
$usuarios = [
    ['id' => 1, 'nombre' => 'Ana'],
    ['id' => 2, 'nombre' => 'Luis'],
    ['id' => 3, 'nombre' => 'María'],
];

$buscado = null;
foreach ($usuarios as $usuario) {
    if ($usuario['id'] === 2) {
        $buscado = $usuario;
        break; // Salir del bucle al encontrar
    }
}

// Generar HTML de una tabla
$datos = [
    ['Producto' => 'Laptop', 'Stock' => 5],
    ['Producto' => 'Mouse', 'Stock' => 50],
];

echo "<table>\n";
foreach ($datos as $fila) {
    echo "<tr>";
    foreach ($fila as $celda) {
        echo "<td>" . htmlspecialchars($celda) . "</td>";
    }
    echo "</tr>\n";
}
echo "</table>";

Ejercicios

Ejercicio 1: Tabla de multiplicar con for

Usa un bucle for para imprimir la tabla de multiplicar del 5 (del 1 al 10).

Ver solucion
<?php

declare(strict_types=1);

$numero = 5;

echo "Tabla del $numero:\n";

for ($i = 1; $i <= 10; $i++) {
    $resultado = $numero * $i;
    echo "$numero x $i = $resultado\n";
}

Ejercicio 2: Sumar elementos con foreach

Dado el array $precios = [19.99, 5.50, 12.00, 8.75], usa foreach para calcular e imprimir la suma total.

Ver solucion
<?php

declare(strict_types=1);

$precios = [19.99, 5.50, 12.00, 8.75];
$total = 0.0;

foreach ($precios as $precio) {
    $total += $precio;
}

echo "Total: $total\n";

Ejercicio 3: Contar hasta condicion con while

Usa un bucle while para imprimir numeros del 1 en adelante hasta que la suma acumulada supere 20. Muestra cada numero y la suma acumulada.

Ver solucion
<?php

declare(strict_types=1);

$numero = 0;
$suma = 0;

while ($suma <= 20) {
    $numero++;
    $suma += $numero;
    echo "Numero: $numero - Suma acumulada: $suma\n";
}

¿Te está gustando el curso?

Tenemos cursos premium con proyectos reales y soporte personalizado.

Descubrir cursos premium