Estructuras de control

Todo script PHP está construido por una serie de sentencias que generalmente finalizan con un punto y coma. Estas sentencias son ejecutadas en PHP en estricto orden secuencial desde el inicio del archivo. Las estructuras de control son usadas para cambiar esta condición.

1. Condicional simple

Al procesar la sentencia IF se evalúa condición si es verdadera se ejecutara solo la primera parte del codigo. Si es falsa se ejecutara solo la segunda parte del código.

if (cond){
	...
}else{
	...
}

También es posible la aplicación simple de la sentencia donde se ejecuta si la condicion es verdadera y no se hace nada si es falsa.

if (cond) sentencia;
cond ? verdadero : falso;
if (3 == $r) func();
$v = 1;
$r = (1 == $v) ? 'Si' : 'No'; // $r es igual a 'Si'
$r = (3 == $v) ? 'Si' : 'No'; // $r es igual a 'No'
$p = true;
echo $p ? 'Verdadero' : 'Falso';

Para comparar un valor contra una variable es mejor hacer valor == variable, porque si te equivocas y usas valor = variable PHP dará error, en cambio si usas variable = valor dentro del IF PHP simplemente reasigna la variable y devolvera TRUE. Mira el siguiente ejemplo.

$x = 3
if ($x = 1) {
	echo 'SIEMPRE se ejecuta esto';
}else{
	echo 'NUNCA se ejecuta esto';
}

También es posible anidar múltiples IF uno dentro de otro de manera infinita.

if (cond1){
	...
}elseif (cond2){
	...
}elseif (cond3){
	...
}else{
	...
}
$n = 5;
if ($n < 0){
   echo 'Numero es negativo';
}elsif ($n <= 10){
   echo 'Numero es 10 o menor';
}else{
   echo 'Numero es mayor que 10';
}

2. Condicional múltiple

Al procesar la sentencia Switch se evalúe la var y se ejecuta cada conjunto de instrucciones hasta el final o hasta encontrar break lo que ocurra primero.

Switch (var){
case (val 1):
	...
	break;
case (val 2):
	...
	break;
case (val 3):
	...
	break;
default:
	...
}

Se pueden usar varios case seguidos sin break si se quiere ejecutar una misma sentencia para varios valores.

Switch ($x){
case (5):
case (4):
case (3):
	echo 'Entre tres y cinco';
	break;
case (2):
	echo 'Dos';
	break;
case (1):
	echo 'Uno';
	break;
default:
	echo 'Cero o mas de cinco';
}

3. Bucle fijo

Al ejecutar la sentencia For, primero se evalúa inicio una sola vez. Normalmente aquí se inicializan las variables. Luego, se evalúa termino y si es verdadera se ejecuta las sentencias, de ser falsa la sentencia For concluye. Finalmente se especifica incremento que es una expresion de alterar la variable cada ciclo. Se puede usar $x = $x + 1, o $x += 1 o $x++ que son sinonimos.

For (inicio;final;incremento){
	...
}
For ($x = 1;$x < 10;$x ++){
	echo $x .'<br>';
}

Se pueden usar varias sentencias separadas por coma.

4. Bucle condicional previo

El bucle While evalúa la cond y ejecuta las sentencias mientras siga siendo verdadera. Notar que cond se evalúan antes de manera que si la cond es falsa desde el inicio nunca se ejecutaran las sentencias ni una sola vez.

While (cond){
	...
}
$x = 1;
While ($x < 10){
	echo $x,'<br>';
	$x++;
}

5. Bucle condicional posterior

El bucle Do While evalúa la cond al final y si cond es verdadera volverá a ejecutar las sentencias mientras cond siga siendo verdadera. Notar que las sentencias se ejecutaran por la menos una vez asi la cond sea falsa desde el inicio.

Do {
	...
} While (cond);
$x = 1;
Do {
	echo $x .'<br>';
	$x++;
} While ($x < 10);

6. Bucle sobre valores

Este blucle solo se usa con matrices y objetos. El bucle recorre un bloque de código para cada elemento de una matriz o cada propiedad de un objeto.

foreach (matriz as $valor){
   sentencias
}
foreach (matriz as $clave => $valor){
   sentencias
}

Al iniciar FOREACH el puntero de la matriz se posiciona automáticamente en el primer valor, por lo que es inecesario llamar a la funcion reset().

	
$a = array(1, 2, 3);
foreach ($a as &$valor) {
   echo $valor * 5;     //Muestra 5, 10 y 15.
}
unset($a);
	
$a = array(2, 4, 6, 8);
foreach ($a as $clave => $valor) {
    echo "{$clave} => {$valor} = $a";
}
	
$lista = array('Peter'=>'35','Ben'=>'37','Joe'=>'43');
foreach ($lista as $key => $value) {
   echo "$key : $value 
"; }

7. Modificación del flujo

7.1 Break

break finaliza la ejecución de la estructuras: switch, for, while, do-while o foreach en curso. Acepta un argumento numérico opcional que indica de cuántas estructuras anidadas circundantes se debe salir. El valor predeterminado es 1, es decir, solamente se sale de la estructura circundante inmediata.

7.2 Continue

continue se usa dentro de las estructuras iterativas para saltar el resto de la iteración actual del bucle y continuar la ejecución en la evaluación de la condición, para luego comenzar la siguiente iteración. Acepta un argumento numérico opcional, que indica a cuántos niveles de bucles encerrados se ha de saltar al final. El valor por omisión es 1, por lo que salta al final del bucle actual.

while (list($clave, $valor) = each($arr)) {
    if (!($clave % 2)) { // saltar los miembros pares
        continue;
    }
    hacer_algo($valor);
}

7.3 GoTo

El operador goto puede ser usado para saltar a otra sección en el programa. El punto de destino es especificado mediante una etiqueta seguida de dos puntos y la instrucción es dada como goto seguida de la etiqueta del destino deseado. Este goto no es completamente sin restricciones. La etiqueta de destino debe estar dentro del mismo fichero y contexto, lo que significa que no se puede saltar fuera de una función o método, ni se puede saltar dentro de uno. Tampoco se puede saltar dentro de cualquier clase de estructura de bucle o switch. Se puede saltar fuera de estos y un uso común es utilizar un goto en lugar de un break multi-nivel.

goto a;
echo 'Primero';
 
a:
echo 'Segundo';

7.4 Return()

Return devuelve el control del programa al módulo que lo invoca. La ejecución vuelve a la siguiente expresión después del módulo que lo invoco.

return('hola);
a.php
<?php
include('b.php');
echo 'a';
?>

b.php
<?php
echo 'b';
return;
?>

Al ejecutar a.php se obtiene la cadera "ba"

Si no se suministra un parámetro, entonces NULL será retornado.

8 Exit() o Die()

Ambas funciones terminan inmediatamente la ejecución del script actual. Si les pasas un texto (string) o un número entero,

exit;
die;
exit(['mensaje']);
die(['mensaje']);

Al usar exit; o die;, si tienes funciones registradas con register_shutdown_function(), estas se ejecutarán antes de que el script se cierre por completo.

a.php
<?php
include('b.php');
echo 'a';
?>

b.php
<?php
echo 'b';
exit;
?>

Al ejecutar a.php se obtiene la cadera "b"

Si pasas un número entero: PHP lo usa como un código de estado de salida (de 0 a 254) para el sistema operativo. No imprime el número. El 0 significa éxito y cualquier otro número indica un error.

$arc = '/ruta/hacia/archivo-datos';
$file = fopen($arc, 'r') or die("no se pudo abrir el archivo ($arc)");

9 Try...catch

La estructura try...catch es la forma estándar de manejar errores o excepciones en PHP modernos sin tener que matar el script con die() o exit(). Te permite atrapar el error, controlarlo y dejar que el código siga corriendo.

try{
   ...
}catch (control $e) {
   ...
}finally{
   ...
}

Quiero dejar claro que solo se ejecutara un bloque.

Jerarquia y origen del problema
controlDescripcion
ExceptionSi quieres atrapar problemas normales de tu lógica.
ErrorSi quieres evitar que fallos del motor de PHP maten tu script. Fallos internos PHP
Throwableatrapar absolutamente cualquier cosa con $e->getMessage()
try {
   // 1. Aquí pones el código que podría fallar
   $resultado = 10 / 0;            // Esto lanzará una excepción (DivisionByZeroError)
}catch (Exception $e) {
   // 2. Si fuera un error de logica, el control saltaria aquí
   echo 'Error de logica: '. $e->getMessage();
}catch (Error $e) {
   // 3. Si fuera un error de PHP, el control saltaria aquí
   // Nota: Desde PHP 7, los errores graves como dividir por cero tambien
   echo 'Error del sistema: '. $e->getMessage();
}catch (Throwable $e) {
   // 4. Si no salto ninguno de lo anteriores llegara aqui
   echo 'Atrapa todo: '. $e->getMessage();
}

El objeto $e (ya sea que herede de Exception, Error o Throwable) viene cargado con varios métodos útiles de fábrica para ayudarte a depurar exactamente qué, cómo y dónde falló tu código.

Metodos para try...catch
MetodoDescripcionEjemplo
getMessage()El texto descriptivo del error."Division by zero" o "Archivo no encontrado"
getCode()El código numérico asignado al error (si se le dio uno).0 (por defecto) o códigos HTTP como 404, 500
getFile()La ruta completa del archivo PHP donde ocurrió el fallo./var/www/html/index.php
getLine()El número de línea exacto donde se originó el problema.42
getTrace()Un array con el historial completo de funciones/métodos que se llamaron hasta llegar al error (el "backtrace").Array ( [0] => Array ( [file] => ... ) )
getTraceAsString()El mismo historial de llamadas (getTrace), pero formateado como un string limpio listo para leer o guardar en un log.#0 /app/User.php(12): Clase->metodo()
getPrevious()El objeto de la excepción anterior (si es que anidaste una excepción dentro de otra).Object(Exception) o null
try {
   // Forzamos un error pasando el tipo de dato incorrecto
   count('esto no es un array'); 
}catch (Throwable $e) {
   echo '

Ups, algo salió mal.

'; echo 'Detalle: '. $e->getMessage() .'
'; echo 'Archivo: '. $e->getFile() .'
'; echo 'Línea: '. $e->getLine() .'

'; echo 'Historial de ejecución (Trace):
'; echo '

'. $e->getTraceAsString() .'
'; }
try{
   $res = $mysqli->query($sql);
}catch (Throwable $e) {
   error_log("script.php = $e->getMessage() = $sql \n",3,'ERROR.log');
   $mysqli->close();
   exit('Error. Intentalo nuevamente.

'); }

10. Sleep()

Detiene la ejecución del programa durante el número de segundos dados.

sleep(n);
$i = 1;
while ($i < 10){
   echo date('h:i:s') ."\n";
   sleep(10);
}

Vea también
FunciónDescripción
usleep()Detiene la ejecución en microsegundos
time_nanosleep()Detiene la ejecución por un número nanosegundos
time_sleep_until()Hacer que el script duerma hasta el momento especificado
set_time_limit()Limita el tiempo máximo de ejecución