Curso de PHP para principiantes

[ Índice | Anterior ]

Control de flujo

1.-Control de flujo

Hasta ahora los programas que hemos visto eran lineales. Comenzaban por la primera instrucción y acababan por la última, ejecutándose todas una sola vez.  Lógico ¿no?. Pero resulta que muchas veces no es esto lo que queremos que ocurra. Lo que nos suele interesar es que dependiendo de los valores de los datos se ejecuten unas instrucciones y no otras. O también puede que queramos repetir unas instrucciones un número determinado de veces. Para esto están las sentencia de control de flujo.

2.-Bucles

Los bucles nos ofrecen la solución cuando queremos repetir una tarea un número determinado de veces. Supongamos que queremos escribir 100 veces la palabra hola. Con lo que sabemos hasta ahora haríamos:

<?php
echo "Hola";
echo "Hola";
echo "Hola";
echo "Hola";
echo "Hola";
echo "Hola";
// seguimos hasta 100 veces...
echo "Hola";
?>

Como es evidente esto sería una locura. Por fortuna PHP nos ofrece una serie de estructuras que permiten crear bucles y ahorrarnos un montón de trabajo. Por ejemplo, esto mismo con el bucle for (veremos el for en la siguiente sección) sería:

<?php
for($i=0; $i<100; i++)
 echo "Hola";
?>

Un poco más difícil de entender la primera vez que se ve pero claramente mucho más rápido de teclear.

2.1.-El bucle for

El bucle for permite repetir una serie de acciones tantas veces como queramos. Tiene el siguiente formato:

for( valores iniciales ; condiciones ; incrementos )
{
 conjunto de intrucciones a ejecutar en el bucle
}

Vamos a estudiarlo con el ejemplo anterior:

<?php
for($i=0; $i<100; i++)
{
 echo "Hola";
}
?>

En este caso asignamos un valor inicial a la variable $i. Ese valor es cero. Esa es la parte de dar valores iniciales. Luego tenemos i<100. Esa es la parte condiciones. En este caso la condición es que i sea menor que 100, de modo que el bucle se ejecutará mientras i sea menor que 100. Es decir, mientras se cumpla la condición. Luego tenemos la parte de incrementos, donde indicamos cuánto se incrementa la variable en cada paso del bucle.

Como vemos, el for va delante del grupo de instrucciones a ejecutar, de manera que si la condición es falsa, esas instrucciones no se ejecutan ni una sola vez.

2.1.1 ¿Cómo funciona el bucle for?

Valores iniciales:

$i = 0;

Paso 0:

se comprueba la condición: ¿ $i < 100 ? $i vale 0 => La condición se cumple.

Ejecutamos las instrucciones del bucle, en este caso: echo "Hola";

Incrementos: $i++ => $i ahora vale 1.

Paso 1:

se comprueba la condición: ¿ $i < 100 ? $i ahora vale 1, que es menor que 100 => La condición se cumple.

Ejecutamos las instrucciones del bucle, en este caso: echo "Hola";

Incrementos: $i++ => $i ahora vale 2.

Paso 2:

se comprueba la condición: ¿ $i < 100 ? $i ahora vale 2, que es menor que 100 => La condición se cumple.

Ejecutamos las instrucciones del bucle, en este caso: echo "Hola";

Incrementos: $i++ => $i ahora vale 3.

...

Paso 99:

se comprueba la condición: ¿ $i < 100 ? $i ahora vale 99, que es menor que 100 => La condición se cumple.

Ejecutamos las instrucciones del bucle, en este caso: echo "Hola";

Incrementos: $i++ => $i ahora vale 100.

Paso 100:

se comprueba la condición: ¿ $i < 100 ? $i ahora vale 100 => La condición NO se cumple => Se termina el bucle.

2.1.2 Notas sobre el for

Cuidado: No se debe poner un ";" justo después de la sentencia for, pues entonces sería un bucle vacío y las instrucciones siguientes sólo se ejecutarían una vez. Veamoslo con un ejemplo:

<?php
for($i=0; $i<100; i++) ;
{
 echo "Hola";
}
?>

Este programa sólo escribirá en pantalla Hola una sola vez.

También puede suceder que quieras ejecutar un cierto número de veces una sola instrucción (como sucede en nuestro ejemplo). Entonces no necesitas las llaves "{}":

<?php
for($i=0; $i<100; i++)
 echo "Hola";
?>

Sin embargo, yo me he encontrado muchas veces que es mejor poner las llaves aunque sólo haya una instrucción; a veces al añadir una segunda instrucción más tarde se te olvidan las comillas y no te das cuenta. Parece una tontería, pero muchas veces, cuando programas, son estos los pequeños fallos los que te vuelven loco.

2.2.-Bucles con While

Los bucles while tienen el siguiente formato:

while( condicion )
{
 código a ejecutar
}

While quiere decir mientras. Aquí se ejecuta el bloque de intrucciones mientras se cumpla la condición impuesta en while.

Veamos su uso con un ejemplo:

<?php
$linea = 1;
while( $linea<=100 )
{
 echo "Estamos en la línea $linea<br/>";
 $linea++;
}
?>

Resultado:

Estamos en la línea 1

Estamos en la línea 2

Estamos en la línea 3

...

Estamos en la línea 100

Vemos que el código:

echo "Estamos en la línea $linea<br/>";

se ejecuta mientras se cumpla la condición:

( $linea <= 100 )

Es importante destacar que en cada pasada del bucle tiene que cambiar algo en la condición porque si no ésta se cumpliría siempre y estaríamos en un bucle infinito. Si quitamos el la parte donde se incrementa el valor de $linea el bucle estaría ejecutándose indefinidamente:

<?php
// Este programa tiene un fallo muy gordo
$linea = 1;
while( $linea<=100 )
{
 echo "Estamos en la línea $linea<br/>";
}
?>

2.3.-¿Cómo funciona el bucle while?

Vamos a ver paso a paso el programa para entender el funcionamiento del bucle while.

Primero damos un valor inicial a la variable $linea:

$linea = 1;

Cuando llegamos al while se comprueba si se cumple la condición: $linea<=100. En la primera ocasión $linea vale 1 por lo tanto la condición se cumple.

while( $linea<=100 )

y se ejecuta el código del bloque que viene después:

 echo "Estamos en la línea $linea<br/>";
 $linea++;

Dado que hemos incrementado el valor de $linea (con $linea++;) ahora $linea valdrá 2.

Volvemos al while y comprobamos la condición de nuevo: $linea sigue siendo menor que 100 así que ejecutamos de nuevo el código.

Ahora $linea valdrá 3: se vuelve a cumplir la condición.

...

Llegará un punto que $linea valdrá 100. La condición es que $linea sea menor o igual que 100, así que también se cumplirá en este caso. Mostramos el mensaje de la línea en la que estamos y se incrementa $linea.

Volvemos al while pero en esta ocasión $linea vale 101 y ya no se cumple la condición => se termina el bucle.

2.4.-Bucles con Do-While

El bucle do-while es muy similar al while. La única diferencia es que, mientras en el bucle while si la condición no se cumple la primera ver no se ejecuta nunca el código dentro de él, en el bucle do-while el bloque de código que viene a continuación se ejecuta al menos una vez (aunque nunca se cumpla la condición).

Formato de do-while:

<?php
do
{
 código a ejecutar
} while( condición );
?>

El ejemplo anterior quedaría:

<?php
$linea = 1;
do
{
 echo "Estamos en la línea $linea<br/>";
 $linea++;
} while( $linea<=100 );
?>

2.5.-Foreach

Existe un tipo especial de bucle que sirve para trabajar con arrays. Dado que aún no conocemos la teoría de los arrays lo veremos más adelante.

2.6.-Bucles infinitos

Hemos visto que en los bucles for, while y do-while que se ejecutan mientras se cumpla una condición. Existe la posibilidad de que esta condición se cumpla siempre. Si eso ocurre nos encontramos ante un bucle infinito.

Aunque PHP tiene un mecanismo de defensa ante los bucles infinitos debemos evitarlos a toda costa porque estaremos consumiendo recursos del servidor innecesariamente.

Algunos ejemplos de bucles infinitos:

<?php
for($i=0; $i>=0; $i++)
 echo "Hola";
?>

En este ejemplo la condición se cumple siempre porque $i siempre es mayor o igual a cero.

<?php

while ( true )

echo "Hola" ;

?>

En este caso la condición siempre es true así que el bucle se ejecuta siempre.

$i = 0;
while($i<10) {
 echo "Hola";
}

2.7.-break

La sentencia break nos permite salir de un bucle for, foreach, while, do-while. Break también se usa en sentencias switch como ya veremos más adelante.

Su utiliadad puede parecer poco clara por ahora, pero se verá más claramente cuando estemos analizando los bucles foreach. Entonces volveremos sobre esta sentencia.

2.8.-Continue

La sentencia continue hace que no se ejecute el resto del código dentro del bloque y se salte a la siguiente "vuelta" del bucle.

Simplemente comentamos aquí su existencia. La estudiaremos cuando lleguemos al apartado de arrays.

3.-Sentencias condicionales

Hasta aquí hemos visto cómo podemos repetir un conjunto de instrucciones las veces que deseemos. Pero ahora vamos a ver cómo podemos controlar totalmente el flujo de un programa. Dependiendo de los valores de alguna variable se tomarán unas acciones u otras. Empecemos con la sentencia if.

3.1.-If

La palabra if significa si (condicional), pero supongo que esto ya lo sabías. Su formato es el siguiente:

<?php
if( condicion )
{
 instrucciones a ejecutar
}
?>

Cuando se cumple la condición entre paréntesis se ejecuta el bloque inmediatamente siguiente al if (bloque instrucciones a ejecutar).

En el siguiente ejemplo tenemos un programa que comprueba un número, si ese número es 10 se muestra un mensaje. Si no es 10 no se muestra ningún mensaje:

<?php
$numero = 10;
if( $numero==10 )
{
 echo "El número es 10";
}
?>

En este caso se mostraría "El número es 10" en la pantalla. Si cambiamos el 10 por un 3 no saldrá nada en el navegador:

<?php
$numero = 3;
if( $numero==10 )
{
 echo "El número es 10";
}
?>

3.2.-If-Else

Formato de if-else:

<?php
if ( condición )
{
 código a ejecutar si se cumple la condición
}
else
{
 código a ejecutar si NO se cumple
}
?>

En el if si no se cumplía la condición no se ejecutaba el bloque siguiente y el programa seguía su curso normal. Con el if else tenemos un bloque adicional que sólo se ejecuta si no se cumple la condición. Veamos un ejemplo:

<?php
$numero = 3;
if( $numero==10 )
{
 echo "El número es 10";
}
else {
 echo "El número NO es 10";
}
?>

En este caso la condicón no se cumple así que se ejecuta el código que está después del else y se muestra el mensaje "El número NO es 10".

3.3.-If-Else-If

Los If-else se pueden anidar tantas veces como se quiera (no conviene anidar demasiados ya que hace los programas más difíciles de "entender").

Ejemplo:

<?php
$numero = 5;
if( $numero==10 )
{
 echo "El número es 10";
}
else if ( $numero==3 ){
 echo "El número es 3";
}
else {
 echo "El número no es 10 ni 3";
}
?>

3.4.-If-Else abreviado: ?

El uso de la interrogación es una forma de condensar un if-else. Se usa a veces para dar mayor claridad a nuestro programa o incluso para ahorrar tecleado. Su formato es el siguiente:

 ( condicion ) ? ( instrucción 1 ) : ( instrucción 2 )

Si se cumple la condición se ejecuta la instrucción 1 y si no se ejecuta la instrucción 2. Veamos un ejemplo con el if-else y luego lo reescribimos con "?":

<?php
$numero = 5;
echo ( $numero==10 ? 'El número es 10' : 'El número NO es 10' );
?>

Aparte de la forma de escribirlo funciona igual que un if-else normal.

3.5.-Switch

El formato de la sentencia switch es el siguiente:

 switch ( variable )
 {
  case opción 1:
   código a ejecutar si la variable tiene el
   valor de la opción 1
   break;
  case opción 2:
   código a ejecutar si la variable tiene el
   valor de la opción 2
   break;
  default:
   código que se ejecuta si la variable tiene
   un valor distinto a los anteriores
   break;
 }

Vamos a ver cómo funciona. La sentencia switch sirve para elegir una opción entre varias disponibles. Aquí no tenemos una condición que se debe cumplir sino el valor de una variable. Dependiendo del valor se cumplirá un caso u otro.

Por ejemplo si la opción elegida fuera la dos se ejecutaría el código que está justo después de:

case opción 2:

hasta el primer break que encontremos.

Vamos a ver un ejemplo de múltiples casos con if-else y luego con switch:

<?php
$numero = 2;
if ($numero==1) {
 echo "Es un 1";
}
else if ($numero==2) {
 echo "Es un 2";
}
else if ($numero==3) {
 echo "Es un 3";
}
else {
 echo "No es un 1 ni un 2 ni un 3";
}
?>

Ahora con switch:

<?php
$numero = 2;
switch($numero) {
 case '1':
  echo "Es un 1";
  break;
 case '2':
  echo "Es un 2";
  break;
 case '3':
  echo "Es un 3";
  break;
 default:
  echo "No es un 1 ni un 2 ni un 3";
  break;
}
?>

Como vemos el código con switch es más cómodo de leer.

Vamos a ver qué pasa si nos olvidamos algún break:

<?php
$numero = 1;
switch($numero) {
 case '1':
  echo "Es un 1";
  // Si nos olvidamos este break
 case '2':
  echo "Es un 2";
  break;
 case '3':
  echo "Es un 3";
  break;
 default:
  echo "No es un 1 ni un 2 ni un 3";
  break;
}
?>

Si al ejecutar el programa $numero vale 2 tenemos el mensaje Es un dos. Todo correcto. Pero si tiene como valor un uno lo que nos sale en pantalla es:

Es un 1

Es un 2

¿Por qué? Pues porque cada caso empieza con un case y acaba donde hay un break. Si no ponemos break aunque haya un case el programa sigue hacia adelante. Por eso se ejecuta el código del case 1 y del case 2.

Puede parecer una desventaja pero a veces es conveniente. Por ejemplo cuando dos case deben tener el mismo código. Si no tuviéramos esta posibilidad tendríamos que escribir dos veces el mismo código.

3.6.-Sintaxis alternativa: otra forma de usar las sentencias de control

En PHP existe una forma alternativa de usar todas estas sentencias de control. Esta forma alternativa es muy conveniente cuando mezclamos PHP y HMTL en nuestros programas ya que los hacen más legibles.

Por ejemplo un IF se puede escribir como hemos visto hasta ahora:

< html >

< body >

<? php

 $numero==10;
 if($numero==1) {
  echo "<p>Es un uno</p>";
 }
 ?>

</ body >

</ html >

o también podríamos hacer:

< html >

< body >

<? php

 $numero==10;
 if($numero==1) {
 ?>

< p > Es un uno </ p >

 <?php } ?>

</ body >

</ html >

Estas dos formas pueden ser bastante confusas para alguien que no está acostumbrado a trabajar con PHP o a programar.

Con la sistaxis alternativa el programa quedaría:

< html >

< body >

 <?php $numero==10; ?>
 <?php if($numero==1): ?>

< p > Es un uno </ p >

 <?php endif ?>

</ body >

</ html >

Que queda más ordenada y legible.

Formas abreviadas:

If

<?php if(condicion): ?>

<? endif; ?>

For

<?php for(inicial; condicion; incremento): ?>

<? endfor; ?>

Foreach (ya lo veremos más adelante)

<? foreach($variable as $otra): ?>

<? endforeach; ?>

While

<? while(condicion): ?>

<? endwhile; ?>

[ Índice | Anterior ]