Bucles en PHP
Los bucles son las estructuras que permite repetir instrucciones de forma automática mientras se
cumpla la condición dada
Imagina que necesitas imprimir una tabla de datos, o que necesitas agrupar multiples valores o
validar una gran cantidad de datos y filtrar solo los necesarios, hacer cualquiera de estas
operaciones u otras operaciones similares conllevarían repetir muchas lineas de código idénticas,
pongamos una tabla de datos para ejemplificar:
$staff = [
[
"name" => "Maria",
"email" => "maria@test.test",
"role" => "administrator",
],
[
"name" => "Luis",
"email" => "luis@test.test",
"role" => "marketing",
],
// ...
[
"name" => "Cris",
"email" => "cris@test.test",
"role" => "producer",
],
];
Imprimir una tabla con estos datos conllevaría un código interminable que dependería de la cantidad
de datos, por ejemplo:
echo "{$staff[0]['name']} - {$staff[0]['email']} - {$staff[0]['role']}<br>";
echo "{$staff[1]['name']} - {$staff[1]['email']} - {$staff[1]['role']}<br>";
// ...
echo "{$staff[2]['name']} - {$staff[2]['email']} - {$staff[2]['role']}<br>";
Para este tipo de casos es que existen las estructuras repetitivas, así que apliquemos una de ellas a
este ejemplo y veamos como se simplifica el código:
foreach($staff as $person){
echo "{$person['name']} - {$person['email']} - {$person['role']}<br>";
}
Si reproduces el código obtendrás la siguiente respuesta:
Luis – luis@test.test – marketing
Cris – Cris@test.test – producer
Para repetir instrucciones relacionadas con arreglos en PHP tenemos el bucle foreach y
es la estructura repetitiva más simple y efectiva para trabajar con listas y tablas de datos.
El bucle foreach permite repetir una o varias instrucciones por cada elemento dentro
de un arreglo.
La sintaxis de este bucle es muy simple, solo se escribe foreach y entre paréntesis indicamos cual es
el arreglo a iterar seguido de la palabra «as», luego una variable que servirá de alías para acceder
al elemento que el bucle esta accediendo en ese momento y finalmente entre llaves indicaremos las
instrucciones a repetir en cada ciclo del bucle.
Acceso a las llaves de un arreglo
El bucle foreach nos permite también acceder a las llaves del arreglo, conociendo la llave podemos
usarla para añadir mas información útil añadiendo una dimensión extra de datos, ademas de que es
necesario poder acceder a la llave para poder modificar los elementos dentro del arreglo.
Para acceder a la llave hay que indicarla en el bucle con una variable alias seguida del operador
«=>» (flecha doble) quedando de la siguiente forma:
foreach($arreglo as $clave => $valor){
// Instrucciones a repetir en cada ciclo ...
}
Veamos un ejemplo para dejarlo claro…
$days = [
1 => 'domingo',
2 => 'lunes',
3 => 'martes',
4 => 'miércoles',
5 => 'jueves',
6 => 'viernes',
7 => 'sábado',
];
foreach($days as $dayNumber => $dayName){
echo "{$dayNumber} - {$dayName}<br>";
}
2 – lunes
3 – martes
4 – miércoles
5 – jueves
6 – viernes
7 – sábado
Este es un arreglo típico en el que tenemos una lista de opciones numerada, donde el número de la
opción si que es importante y es un dato que nos interesa conocer.
Ahora veamos como recorrer una tabla de datos anidando bucles foreach, para este ejemplo usaremos una
tabla de datos de usuarios y vamos a imprimirla en forma de una tabla HTML.
$users = [
[
'id' => 3200,
'name' => 'Juan Perez',
'email' => 'juan@app.test',
'status' => 1,
],
[
'id' => 3201,
'name' => 'Cris Rodriguez',
'email' => 'cris@app.test',
'status' => 0,
],
[
'id' => 3202,
'name' => 'Luis Hernández',
'email' => 'Luis@app.test',
'status' => 1,
],
[
'id' => 3203,
'name' => 'Juana Alvarez',
'email' => 'juana@app.test',
'status' => 1,
],
];
echo "<table>";
foreach($users as $user){
echo "<tr>";
foreach($user as $property => $value){
echo "<td><strong>{$property}</strong>: {$value}</td>";
}
echo "</tr>";
}
echo "</table>";
| id: 3200 | name: Juan Perez | email: juan@app.test | status: 1 |
| id: 3201 | name: Cris Rodriguez | email: cris@app.test | status: 0 |
| id: 3202 | name: Luis Hernández | email: Luis@app.test | status: 1 |
| id: 3203 | name: Juana Alvarez | email: juana@app.test | status: 1 |
Saltar instrucciones dentro de un bucle
Para saltar ciclos completos o instrucciones especificas dentro de un bucle tenemos la instrucción
continue;, la cual le dice a PHP que salte al siguiente ciclo sin importar que otras
instrucciones estuvieran después.
Para ejemplificarlo vamos a recorrer el mismo arreglo de hace un momento, pero vamos a hacer que
salte a los usuarios con los id 3201 y 3202:
echo "<table>";
foreach($users as $user){
if($user['id'] == 3201 || $user['id'] == 3202){
continue;
}
echo "<tr>";
foreach($user as $property => $value){
echo "<td><strong>{$property}</strong>: {$value}</td>";
}
echo "</tr>";
}
echo "</table>";
| id: 3200 | name: Juan Perez | email: juan@app.test | status: 1 |
| id: 3203 | name: Juana Alvarez | email: juana@app.test | status: 1 |
Detener la ejecución de un bucle
Para poder detener por completo un bucle usamos la instrucción break;
Para ver como se detiene una estructura repetitiva un bucle hagamos que el bucle solo imprima hasta
el usuario del id 3201:
echo "<table>";
foreach($users as $user){
echo "<tr>";
foreach($user as $property => $value){
echo "<td><strong>{$property}</strong>: {$value}</td>";
}
echo "</tr>";
if ($user['id'] == 3201) {
break;
}
}
echo "</table>";
| id: 3200 | name: Juan Perez | email: juan@app.test | status: 1 |
| id: 3201 | name: Cris Rodriguez | email: cris@app.test | status: 0 |
Bucle For
Este bucle repetirá las instrucciones indicadas hasta que se deje cumplir una condición dada.
El bucle For se utiliza cuando se quieren repetir las instrucciones deseadas una cantidad especifica
de veces.
Para usar el bucle for es necesario saber que este se compone de varias partes, primero en su
definición tenemos 3 secciones:
- Inicialización: Se definen una o multiples variables antes de empezar con el bucle, normalmente
aquí se define un valor para llevar la cuenta de cuantas veces se ha ejecutado el bucle - Evaluación: Se evalúa una condición en cada ciclo para determinar si el bucle debe continuar una
vez más o detenerse - Cambio con cada ciclo: Se cambia algún valor en cada ciclo, lo normal suele ser cambiar el valor
de la variable que lleva la variable definida en un inicio que lleva la cuenta.
Suena mas complicado de lo que realmente es, veamos como quedaría finalmente el bucle for:
for($i=1; $i<=10; $i++){
echo "{$i}<br>";
}
Si corremos este trozo de código el bucle imprimirá los números del 1 al 10.
La variable $i sirve para definir un valor inicial que llevara la cuenta, luego tenemos la condición
que mientras $i sea menor o igual a diez el bucle debe repetir la instrucción definida y en cada
ciclo debe aumentar en uno el valor de $i y finalmente la instrucción a repetir es la de imprimir el
valor que lleva la cuenta.
Veamos otro ejemplo, en un sitio donde se tiene cierta cantidad de elementos y se desea paginar esos
elementos, sabiendo la cantidad de paginas existentes (13 por ejemplo), usando el bucle for podemos
generar la paginación de forma simple:
for($i=1; $i<=13; $i++){
echo "<a href=\"http://localhost/app?page={$i}\">{$i}</a> ";
}
Iterar arreglos con el bucle For
El bucle for se puede usar también para recorrer arreglos simples, de hecho en otros lenguajes de
programación el bucle for es el modo estándar para iterar sobre arreglos.
¿Pero en PHP que sentido tendría usar el bucle for sobre el mas simple y cómodo bucle foreach?
Pues con el bucle for podemos iterar arreglos sin tener que empezar por el inicio, podemos por
ejemplo recorrerlos en reversa.
Veamos el ejemplo anterior de imprimir un arreglo con los días de la semana pero ahora en reversa:
$days = [
1 => 'domingo',
2 => 'lunes',
3 => 'martes',
4 => 'miércoles',
5 => 'jueves',
6 => 'viernes',
7 => 'sábado',
];
for($i = 7; $i>0; $i--){
echo "{$i} - {$days[$i]}<br>";
}
6 – viernes
5 – jueves
4 – miércoles
3 – martes
2 – lunes
1 – domingo
Hay que poner mucha atención a la condición del bucle y al valor que se cambia en cada ciclo, si el
valor no se cambiase correctamente el ciclo no terminaría y se ejecutaría infinitamente (ó hasta que
el motor de php alcance el límite de memoria asignado.) y si la condición es incorrecta el bucle
podría no ejecutarse o podría ejecutarse menos o más veces de las esperadas.
El bucle while
Esta estructura repetitiva permite ejecutar multiples veces las instrucciones que agrupa en su
interior mientras se cumpla una condición dada, la cual se evalúa en cada repetición. Este bucle
tiene la siguiente sintaxis:
while($condicion){
// Instrucciones a repetir...
}
El bucle while es más sencillo pero más flexible que los bucles anteriores.
Iterar arreglos con el bucle While
al igual que los bucles anteriores puede usarse para recorrer arreglos, aunque lo mas fácil sería
recorrerlos con foreach o con for, pero veamos como sería para entender la sintaxis de este bucle.
$colors = ['red', 'green', 'blue'];
$i = 0;
while($i < 3){
echo "{$colors[$i]}<br>";
$i++;
}
Al igual que con el bucle for, para recorrer arreglos tendríamos que definir una variable que lleve
la cuenta, luego debemos definir la condición que se evaluara para saber si el ciclo debe continuar
o no y por último debemos incrementar el valor de la variable que lleva la cuenta, pero de estas
tres cosas ninguna forma parte del bucle propiamente.
Para que veas a a que me refiero veamos un bucle while sin una condición que evaluar:
$colors = ['red', 'green', 'blue'];
$i = 0;
while (true) {
echo "{$colors[$i]}<br>";
$i++;
if($i >= 3){
break;
}
}
El bucle while puede simplemente usarse pasándole el valor booleano true para que se ejecute
indefinidamente, pero para que no de lugar a un bucle infinito dentro de las instrucciones del bucle
podemos evaluar cuando debería detenerse y usar la instrucción break para finalizar el
bucle.
Para ejemplificar un bucle que se ejecuta indefinidamente veamos un algoritmo muy común
Este algoritmo se usa para generar una lista de horarios de disponibilidad (pueden ser horarios de
atención en un consultorio, horarios estimados de salida y llegada para una ruta de algún
transporte, espacios de alquiler de un aula o un local, etc.)
El código sería el siguiente y en seguida lo desgranaremos:
$startingHour = 8;
$endingHour = 10;
$duration = 40;
$slots = [];
$slotHour = $startingHour;
$slotMinute = 0;
while (true) {
$slots[] = [
'hour' => $slotHour,
'minute' => $slotMinute
];
$slotMinute += $duration;
if ($slotMinute >= 60) {
$slotMinute -= 60;
$slotHour++;
}
if ($slotHour >= $endingHour) {
break;
}
}
echo "<h3>Horarios disponibles</h3>";
echo "<ul>";
foreach ($slots as $time) {
if (0 == $time['minute']) {
$time['minute'] = '00';
}
echo "<li>{$time['hour']}:{$time['minute']}</li>";
}
echo "</ul>";
Horarios disponibles
- 8:00
- 8:40
- 9:20
- 10:00
- 10:40
- 11:20
- 12:00
- 12:40
- 13:20
Lo primero es empezar definiendo 3 valores iniciales necesarios para el funcionamiento, la hora de
inicio, la hora de finalización y la duración (en minutos) o tiempo separación entre
disponibilidades.
Después tenemos el arreglo que almacenara la lista de horarios disponibles seguido de dos valores que
llevan la cuenta de la hora y minuto que irán cambiando con cada ciclo.
Luego tenemos nuestro bucle while que se ejecutara indefinidamente
Dentro del bucle tenemos la instrucción de guardar el horario en cada iteración, el cual ira
cambiando en intervalos definidos por la duración establecida.
En seguida tenemos el calculo del tiempo, en el que se suma la variable con la duración a la variable
que lleva la cuenta de los minutos y por cada 60 minutos que se completen, se debe volver a empezar
en cero los minutos y se debe incrementar en uno la variable que lleva la cuenta de las horas.
Por ultimo dentro del bucle tenemos la condición que detendrá la ejecución del bucle para evitar que
siga calculando horarios infinitamente.
En cuanto el valor que lleva la cuenta de las horas alcance al valor de la hora de finalización
detenemos el ciclo.
Ahora simplemente imprimimos en HTML una lista con los horarios que generamos usando un bucle
foreach.
