Estructuras de control de repetición en PHP. Explicaciones y ejemplos de los bucles while, do-while, for y foreach. Además veremos las sentencias de control de bucles break y continue.
Estamos abordando el tema de las estructuras de control en PHP. En el pasado artículo conocimos las estructuras condicionales y en este vamos a tratar las estructuras de bucles o repeticiones. Ambas son básicas para la realización de algoritmos y todo tipo de programas.
Los ordenadores, como cualquier máquina, están diseñados para realizar tareas repetitivas. Es por ello que nuestros programas pueden aprovecharse de este principio para realizar una determinada secuencia de instrucciones un cierto número de veces. Para ello, utilizamos las estructuras llamadas en bucle que nos ayudan a, usando unas pocas líneas, realizar una tarea incluida dentro del bucle un cierto numero de veces definido por nosotros mismos.
Estructuras de repetición en PHP
A las estructuras de control de repetición, a las que llamamos bucles de manera coloquial, nos permiten realizar la ejecución de una o más sentencias de manera repetida, lo que es muy importante a la hora de componer algoritmos.
Los bucles se usan para muchas cosas, siendo una de las más importantes el recorrido de estructuras de datos como los arrays. Además en todo tipo de algoritmos en los que quieras iterar por distintos elementos. Casos de uso serían recorrer un archivo de texto línea a línea, realizar una entrada de datos hasta que el usuario escriba un dato en el formato necesario, etc.
Para realizar las repeticiones en los lenguajes de programación suelen aportarse distintos tipos de estructuras que vamos a resumir antes de empezar a tratarlas con detalle:
- Estructura for: permite configurar una repetición de manera muy explícita, indicando qué variable vamos a usar para llevar la cuenta de las repeticiones, hasta qué punto vamos a seguir repitiendo, etc.
- Estructura while: permite comprobar si se cumple una condición y si es así, ejecutar un código... que se repetirá hasta que no se cumpla la expresión.
- Estructura do-while: es una variante del while pero donde primero se ejecuta el cuerpo del bucle y una vez se ha ejecutado se comprueba si se cumple la expresión, en cuyo caso se sigue repitiendo el bucle.
Cuándo usar una estructura de repetición u otra
Una de las cosas que nos preguntamos cuando estamos empezando es: de entre todas las posibles estructuras de repetición ¿cuál es la que debo de utilizar? La respuesta te la da la experiencia, por lo que en realidad cuando tengas un poco de tiempo programando no tendrás dudas de cuál puede ser la mejor para tu problema. De todos modos, estas serían unas ideas básicas iniciales para saber qué tipo de bucle usar:
- Usa el bucle
for
cuando sepas de antemano cuántas veces necesitas hacer una repetición - Usa el bucle
while
cuando no sabes a priori cuántas veces se va a realizar la iteración, pueden ser más o menos dependiendo de cómo vayan las cosas. - Usa el bucle
do-while
cuando no sabes cuántas veces se va a tener que iterar pero sabes que, al menos, será necesaria una iteración.
Esos son los tres tipos de estructuras de control de repetición, que están en casi todos los lenguajes, pero enseguida veremos que no son las únicas. Por ejemplo PHP también nos ofrece foreach para recorrer estructuras de arrays cómodamente. Las veremos también un poco más abajo.
Un ejemolo de bucle donde sería adecuado usar un for
sería recorrer un array hasta el final, o mostrar la tabla del 9. Luego, el uso de while
y do-while
a veces es indistinto y tiene pequeños matices que pueden llevarte a elegir uno u otro, pero generalmente con pocos cambios en tu código se adaptaría bien una u otra alternativa. Por ejempolo para pedir al usuario un número entero entre 1 y 10 podrías usar el do-while
, dado que al menos se lo tendrás que pedir una vez. Un ejemplo donde podrías usar el bucle while
sería recorrer un array hasta que encuentras un valor determinado pues quizás en la primera casilla ya tenías el valor que buscabas y no necesitabas repetir nada.
De entre todos los bucles vamos a comenzar por los while y do-while porque son un poco más sencillos y legibles.
Bucle while
Sin duda el bucle más utilizado y el más sencillo. Lo usamos para ejecutar las instrucciones contenidas en su interior siempre y cuando la condición definida sea verdadera. La estructura sintáctica es la siguiente.
while (condición)
{
instruccion1;
instruccion2;
...
}
En el anterior pseudo-código hemos querido expresar que existe una condición y siempre que se cumpla se ejecutarán las instrucciones 1 y 2, o cualquier número de sentencias que coloques entre las llaves.
Un ejemplo sencillo es este bucle que aumenta el tamaño de la fuente en una unidad a cada nueva vuelta por el bucle:
<?php
$size = 1;
While ($size <= 6)
{
echo"<span style=\"font-size: {$size}rem\">Tamaño {$size}rem</span><br>\n";
$size++;
}
?>
A modo de explicación, diremos que, antes de nada, hemos de definir el valor de la variable que vamos a evaluar en la condición. Algo absolutamente obvio pero fácil de olvidar. En este caso le hemos atribuido un valor de 1 que corresponde a la letra más pequeña.
El paso siguiente es crear el bucle en el que imponemos la condición que la variable no exceda el valor de 6.
La instrucción a ejecutar será imprimir en nuestro documento un código HTML en el que la etiqueta span
y el mensaje que contiene varían a medida que $size
cambia su valor.
El siguiente paso es incrementar en una unidad el valor de $size
. Esto se puede hacer con una expresión como la mostrada en el bucle ($size++
) que en realidad es sinónima de:
$size = $size + 1
Veremos otras de estas abreviaciones más adelante.
Otros ejemplos del bucle while en PHP
El bucle while se suele utilizar cuando no se sabe exactamente cuantas iteraciones se deben realizar antes de acabar. Vamos a utilizarlo en otro ejemplo, en el que hay que recorrer una cadena hasta encontrar un carácter dado. Si lo encuentra, escribir su posición. Si no, escribir que no se ha encontrado.
Para hacer este ejercicio necesitamos conocer la función de cadena strlen(), que obtiene la longitud de la cadena que se le pase por parámetro.
int strlen (string cad)
Devuelve un entero igual a la longitud de la cadena.
<?php
$cadena = "hola a todo el mundo";
//recorro la cadena hasta encontrar una "m"
$i = 0;
while ($i < strlen($cadena) && $cadena[$i] != "m"){
$i++;
}
if ($i == strlen($cadena)) {
echo "No se encuentra...";
} else {
echo "Está en la posición $i";
}
?>
En este ejemplo se define una cadena con el valor "hola a todo el mundo"
. Posteriormente se recorre esa cadena hasta el final de la cadena o hasta encontrar el caracter "m"
, utilizando una variable $i
que lleva la cuenta de los caracteres recorridos.
Una vez se ha ejecutado el bucle while, si se salió porque se encontró el caracter "m"
, la variable $i
valdrá un número menor que la longitud de la cadema. Si se salió por llegar al final de la cadena, la variable $i
valdrá lo mismo que la longitud en caracteres de esa cadena. En el condicional simplemente se comprueba si $i
vale o no lo mismo que la longitud de la cadena, mostrando los mensajes adecuados en cada caso.
Es muy interesante apreciar la condición del bucle while, que es un poco avanzada, ya que comprueba dos cosas distintas. Primero la parte $i < strlen($cadena)
nos permite asegurarnos que no nos salimos de los límites de la cadena. Luego la parte $cadena[$i] != "m"
nos dice si hemos encontrado lo que buscábamos. Es importante que primero se compruebe que no nos salimos de la cadena, porque si no ocurriría que en la segunda parte del condicional se interntaría acceder a una posición de la cadena inexistente.
Veamos un tercer ejemplo de código con el bucle while
. En este ejemplo queremos acumular la suma de los valores de un array de números hasta que lleguemos a 10 o más.
<?php
$numeros = [1, 5, 13, 50];
// Voy sumando las posiciones de un array hasta que llegue a 10
$posicion = 0;
$suma = 0;
while ($posicion < count($numeros) && $suma < 10) {
$suma += $numeros[$posicion];
$posicion++;
}
echo "La suma a la que he llegado es {$suma}";
?>
Puedes ver que se necesitan dos variables para el bucle, la posición por la que vamos en el array y la suma total que llevamos acumulada.
Bucle do-while
Este tipo de bucle no difiere en exceso del anterior. De hecho es el mismo esquema de funcionamiento con la diferencia que la condición se comprueba al final del cuerpo del bucle. La sintaxis es la siguiente:
do
{
instruccion1;
instruccion2;
...
}
while (condición)
La diferencia con respecto a los bucles while
es un pequeño matiz, pero a veces es representativa. Como hemos dicho, este tipo de bucle evalúa la condición al final con lo que, incluso siendo falsa desde el principio, éste se ejecuta al menos una vez.
En este ejemplo vamos a sacar números aleatorios entre el 1 y el 9, y seguiremos sacando números mientras que el número aleatorio que haya salido sea menor que 8.
<?php
do {
$aleatorio = mt_rand(1,9);
echo "Ha salido $aleatorio<br>";
} while ($aleatorio < 8);
?>
Puedes ver que vamos iterando mientras se cumple la condición, pero al menos tenemos que iterar una vez, dado que por lo menos siempre necesitamos el primer número aleatorio para trabajar.
Ahora que ya conocemos los bucles más sencillos de escribir vamos con el que nos falta, que es el bucle for
, para iterar un número dado de veces y conoceremos algunas otras variantes como foreach
, útil para recorrer arrays
Bucle for
PHP está provisto de otros tipos de bucle que también resultan muy prácticos en determinadas situaciones. El más popular de ellos es el bucle for que, como para los casos anteriores, se encarga de ejecutar las instrucciones que hay entre llaves. La diferencia con los anteriores radica en cómo se plantea la condición de finalización del bucle. Para aclarar su funcionamiento vamos a expresar el primer ejemplo de bucle while visto en el capítulo anterior en forma de bucle for:
<?php
for ($size = 1; $size <= 6; $size++) {
echo"<span style=\"font-size: {$size}rem\">Tamaño {$size}rem</span><br>\n";
}
?>
Las expresiones dentro del paréntesis definen respectivamente:
- Inicialización de la variable. Valida para la primera vuelta del bucle.
- Condición de evaluación a cada vuelta. Si es cierta, el bucle continua.
- Acción a realizar al final de cada vuelta de bucle.
Como hemos podido comprobar, el bucle for es capaz de definir muchos parámetros del bucle en su cabecera, por lo que es una estructura muy potente. Esto se demuestra porque hemos conseguido hacer lo mismo con menos líneas de código.
Uso de las llaves para el cuerpo del bucle
Antes de ver el suguiente tipo de bucle quiero comentar algo que es importante que sepas. Cuando el bucle no tiene más que una sentencia es posible omitir las llaves que engloban las sentencias del cuerpo. Por tanto, el ejemplo anterior se podría escribir también así:
<?php
for ($size = 1; $size <= 6; $size++) echo"<span style=\"font-size: {$size}rem\">Tamaño {$size}rem</span><br>\n";
?>
Esto ocurre también con las sentencias de un condicional if como el que conocimos en el artículo anterior. Sin embargo, aunque ahorres espacio, no es recomendable hacerlo porque dificulta la lectura del código por los humanos. Por eso por buenas prácticas siempre colocaremos las llaves aunque solamente tengamos una sentencia dentro.
Bucle foreach
Este bucle, implementado en las versiones de PHP 4 en adelante, nos ayuda a recorrer los valores de un array lo cual puede resultar muy útil por ejemplo para efectuar una lectura rápida del mismo. Recordamos que un array es una variable que guarda un conjunto de elementos (valores) catalogados por claves.
La estructura general es la siguiente:
foreach ($array as $clave => $valor)
{
instruccion1;
instruccion2;
}
Un ejemplo práctico es la lectura de un array lo cual podría hacerse del siguiente modo:
<?php
$moneda = [
"España"=> "Euro",
"Reino Unido" => "Libra",
"USA" => "Dólar"
];
foreach ($moneda as $clave => $valor) {
echo "Pais: $clave Moneda: $valor<br>";
}
?>
Este script se encargaría de mostrarnos por pantalla el contenido del array $moneda
de una manera legible. Como has visto, el bucle foreach es muy cómodo porque nos dispensa llevar variables con los índices del array. El propio PHP nos los proporciona.
Como bonus te voy a dejar una función genérica basada en este bucle que nos permitie visualizar arrays monodimensionales. Esta función podría ser definida de esta forma:
function mostrar_array ($array) {
foreach ($array as $clave=>$valor) {
echo "$clave=>$valor<br>";
}
}
Sentencias break y continue
Estas dos instrucciones sirven para manipular de manera arbitraria el funcionamiento de los bucles. Se deben colocar dentro del cuerpo del bucle para cambiar el funcionamiento normal del mismo. Funcionan de la siguiente manera:
- Sentencia break: Nos sirve para escapar del bucle, es decir, parar su ejecución inmediatamente.
- Sentencia continue: Nos sirve para saltar a la iteración siguiente del bucle y por tanto detener la iteración actual.
Pueden resultarnos muy prácticas en algunas situaciones.
- Durante una iteración de un bucle podemos saltar directamente a la siguiente iteración, sin seguir con la actual, con la instrucción continue.
- También podemos detener completamente las repeticiones de cualquier bucle con break, lo que parará la ejecución de la iteración actual y de las siguientes que pudiera haber.
Sin embargo, no se recomiendan usar porque rompen con el flujo normal de los programas y si no las apreciamos en el código en una lectura rápida de un bucle podemos pensar que se hace algo y al ver el cuerpo por culpa de un break o un continue colocado dentro el bucle puede estar haciendo otra cosa totalmente distinta a lo que parecía.
Por ejemplo, tomando como base un código anterior:
<?php
$moneda = [
"España"=> "Euro",
"Reino Unido" => "Libra",
"USA" => "Dólar"
];
foreach ($moneda as $clave => $valor) {
echo "Pais: $clave Moneda: $valor<br>";
break;
}
?>
Si leemos el bucle foreach nos damos cuenta que vamos a recorrer todos los elementos de un array. Sin embargo, hay un break, por lo que solamente se mostrará el primer elemento. Esto puede confundir bastante si no se hace una lectura con detenimiento del código. Claro que este ejemplo es muy tonto, pero piensa en un bucle con un cuerpo mucho mayor en el que el break pueda estar más escondido.
Para una ayuda práctica sobre estos bucles ver el siguiente videotutorial Estructuras de control, Vídeo 2: bucles for, while y do-while. Además, las explicaciones sobre estructuras de control se complementan con el videotutorial de Switch y las instrucciones break y continue.
Rubén Alvarez
Rubén es doctor en química y programador principalmente en sus ratos libres con...