====== 02 - PHP III: Estructuras de control ======
===== Condicionales =====
==== if ====
El condicional simple, se escribe con la expresión [[https://www.php.net/manual/es/control-structures.if.php|if]]. Podemos añadir un bloques //else// al condional.
if ($a < 5) {
# codigo...
} else {
# codigo...
}
También podemos usar [[https://www.php.net/manual/es/control-structures.elseif.php|elseif]] para añadir más condiciones:
if ($a < 5) {
# codigo...
} elseif ($a < 10){
# codigo...
} else {
# codigo...
}
==== switch ====
Para el condicional múltiple, usaremos la expresión [[https://www.php.net/manual/es/control-structures.switch.php|switch]].
switch ($a) {
case 0:
# codigo...
break;
case 1:
# codigo...
break;
default:
# codigo...
break;
}
La lista de sentencias para un caso también puede estar vacías, lo que pasará el control a la lista de sentencias para el siguiente caso.
switch ($a) {
case 0:
case 1:
case 2:
# codigo1...
break;
case 3:
# codigo2...
break;
default:
# codigo3...
break;
}
En este caso, tanto si //\$a// vale 0, 1 o 2 se ejecutará //codigo1//.
No hay que olvidarse de añadir //break// al final de cada opción. En caso contrario, PHP seguiría ejecutando las sentencias del caso siguiente.
Para añadir la opción por defecto, utilizaremos //default//.
===== Bucles =====
==== while ====
Los bucles [[https://www.php.net/manual/es/control-structures.while.php|while]] son el tipo de bucle más sencillo en PHP. Se comportan igual que su contrapartida en C. La forma básica de una sentencia //while// es:
while ($a <= 10) {
# codigo...
}
==== do-while ====
Los bucles [[https://www.php.net/manual/es/control-structures.do.while.php|do-while]] son muy similares a los bucles //while//, excepto que la condición es verificada al final de cada iteración, en lugar de al principio. La principal diferencia es que en un bucle //do-while// se ejecutará la primera iteración siempre, mientras que un bucle //while// no tiene porque.
do {
# codigo...
} while ($a <= 10);
==== for ====
Los bucles [[https://www.php.net/manual/es/control-structures.for.php|for]] son los más complejos en PHP. Se comportan como sus homólogos en C. La sintaxis de un bucle //for// es:
for ($i=0; $i < 5; $i++) {
# codigo...
}
PHP ofrece la posibilidad de usar expresiones vacías en los bucles //for//, lo que puede resultar útil en alguna ocasión.
for ($i=0; ; $i++) {
if ($i < 5) {
break;
}
echo $i;
}
Para salir de cualquier bucle, se puede utilizar //break//, mientras que para continuar con la siguiente iteración podemos usar //continue//.
==== foreach ====
El constructor [[https://www.php.net/manual/es/control-structures.foreach.php|foreach]] proporciona un modo sencillo de iterar sobre //arrays//. //foreach// funciona sólo sobre //arrays// y objetos, y emitirá un error al intentar usarlo con una variable de un tipo diferente de datos o una variable no inicializada. Existen dos sintaxis:
foreach ($array1 as $value) {
# codigo...
}
foreach ($array1 as $key => $value) {
# codigo...
}
La primera forma recorre el //array// //$array1//. En cada iteración el valor del elemento actual se asigna a //$value// y el puntero interno del array avanza una posición.
La segunda forma además asigna la clave del elemento actual a la variable //$key// en cada iteración.
PHP ofrece una sintaxis alternativa para algunas de sus estructuras de control, a saber: //if//, //while//, //for//, //foreach//, y //switch//. En cada caso, la forma básica de la sintaxis alternativa es cambiar la llave de apertura por dos puntos (:) y la llave de cierre por //endif;//, //endwhile;//, //endfor;//, //endforeach;//, o //endswitch;//, respectivamente.
===== Incluir archivos externos =====
En PHP podemos incluir varios archivos externos en nuestros //scripts//. Estos archivos pueden ser otros PHPs, HTMLs… Esta práctica es habitual a la hora de estructurar la programación y así poder reutilizar el código el diferentes //scripts// de nuestras webs.
Para incluir archivos externos podemos usar dos sentencias: **include** o **require**.
La sentencia [[https://www.php.net/manual/es/function.include.php|include]] incluye y evalúa el archivo especificado.
Si el archivo no se encuentra en la ruta dada, //include// emitirá una advertencia (//warning//. Si no se da ninguna ruta, PHP buscará primero en el //include_path// especificado en el archivo //php.ini//, después en el propio directorio del //script// que hace la llamada y en el directorio de trabajo actual antes de fallar.
Usar la sentencia //include// equivale a cortar y pegar el contenido del archivo incluido en nuestro //script//.
Por ejemplo, si tenemos el fichero //archivo1.php// con el siguiente contenido:
echo "Hola, soy el archivo 1";
Lo podemos incluir en un segundo fichero //archivo2.php//:
echo "Hola, soy el archivo 2";
include "archivo1.php";
{{ :clase:daw:dws:1eval:estructuras01.png?400 |}}
Como ves, la sentencia //include// es muy útil para separar y estructurar nuestro código.
Una cosa a tener en cuenta es que si incluimos dos veces el mismo archivo PHP no comprobará si ya está incluido, y lo volverá a incluir.
Para que no vuelva a incluir un fichero ya incluido podemos usar la sentencia [[https://www.php.net/manual/es/function.include-once.php|include_once]]. Tiene un comportamiento similar al de la sentencia //include//, con la diferencia que si el código del fichero ya se ha incluido, no se volverá a incluir, e //include_once// devolverá //TRUE//.
La sentencia [[https://www.php.net/manual/es/function.require.php|require]] es exactamente igual que //include//, excepto que en caso de fallo producirá un error fatal de nivel //E_COMPILE_ERROR//. En otras palabras, éste detiene el //script//, mientras que //include// sólo emitirá una advertencia, lo cual permite continuar el //script//.
Para ver la diferencia, modifica //archivo2.php// y cambia la ruta de //include// por algún archivo que no exista. A continuación saca por pantalla la frase //Hola mundo//:
echo "Hola, soy el archivo 2";
include "archivo3.php";
echo "Hola mundo";
Si vemos la salida en el navegador observamos que aunque nos de una advertencia, el //script// sigue ejecutándose mostrando la frase //Hola mundo// al final.
{{ :clase:daw:dws:1eval:estructuras02.png?200 |}}
Ahora cambia //include// por //require// y comprueba la salida.
{{ :clase:daw:dws:1eval:estructuras03.png?200 |}}
En esta ocasión, el intérprete PHP nos advierte del fallo y además nos da un //Fatal error//. Además, ya no saca la frase //Hola mundo//, ya que en cuanto genera el error detiene el //script//.
¿Cuándo utilizar //include// y cuando //require//? Cuando el código a insertar sea imprescindible para el funcionamiento de nuestro script, debemos utilizar //require//. En caso contrario, usaremos //include// para que nuestra web pueda seguir funcionando.
Puede que veas alguna vez usar //include// o //require// como si fueran funciones:
require(“archivo3.php");
Aunque esa sintaxis funcione sin problemas, //include// o //require// no son funciones, si no sentencias que forman parte de la estructura de control, por eso se aconseja utilizar la primera forma.
Igual que //include_once//, también existe [[https://www.php.net/manual/es/function.require-once.php|require_once]], que verificará si el archivo ya se ha incluido.
Tenemos que tener en cuenta que tanto //include_once// como //require_once// requieren más tiempo de procesamiento, ya que el analizador tiene que comprobar si los archivos ya están incluidos.
En cualquier caso, muchas veces nos interesa usar //include_once// o //require_once// para evitar redefinición de funciones, reasignación de valores a las variables, redefinición de clases...
===== Excepciones =====
PHP tiene un modelo de [[https://www.php.net/manual/es/language.exceptions.php|excepciones]] similar al de otros lenguajes de programación. Se puede lanzar una excepción (//throw//), y atraparla (//catch//).
El código puede estar dentro de un bloque //try// para facilitar la captura de excepciones potenciales. Cada bloque //try// debe tener al menos un bloque //catch// o //finally// correspondiente.
Se pueden usar múltiples bloques //catch// para atrapar diferentes clases de excepciones. La ejecución normal (cuando no es lanzada ninguna excepción dentro del bloque try) continuará después del último bloque //catch// definido en la secuencia.
Las excepciones pueden ser lanzadas (//throw//) dentro de un bloque //catch//. Cuando una excepción es lanzada, el código siguiente a la declaración no será ejecutado, y PHP intentará encontrar el primer bloque //catch// coincidente.
Si una excepción no es capturada, se emitirá un //Fatal Error// de PHP con un mensaje //Uncaught Exception...//, a menos que se haya definido un manejador con //set_exception_handlet()//.
En PHP, se puede utilizar un bloque //finally// después o en lugar de bloques //catch//. El código de dentro del bloque //finally// siempre se ejecutará después de los bloques //try// y //catch//, independientemente de que se haya lanzado una excepción o no, y antes de que la ejecución normal continúe.
try {
//codigo...
} catch (Exception $e) {
//codigo...
} finally {
//codigo...
}
===== Ejercicios =====
**Ejercicio 1**
Para no romper la costumbre, nuestro primer ejercicio será crear un archivo PHP que imprima mediante //echo// o //print// la frase //Hello World//.
**Ejercicio 2**
Modifica el ejercicio anterior para que la primera palabra (//Hello//) esté contenida en una variable.
**Ejercicio 3**
Crear una página HTML donde se mostrará un título con la etiqueta //
//. Ese título será el valor de una variable PHP (puedes elegir cualquier título).
**Ejercicio 4**
Hacez un programa en PHP que calcule el mayor de dos números almacenados en dos variables usando el condicional //if//.
**Ejercicio 5**
Crear un archivo PHP que dados dos números almacenados en dos variables, nos muestre por pantalla el mayor de ellos o la frase //Los números son iguales// si son iguales. Usar la estructura //switch// y el operador //nave espacial//.
**Ejercicio 6**
Haz un programa que indicada una nómina en una variable, si es menor de 800€ le haga un incremento del 20%, si está entre 800 € y 1200 € la deje como está, y si es mayor le quite un 15%. Usar el condicional //if//.
**Ejercicio 7**
Haz un programa en PHP que defina una constante //LÍMITE// y genere un número aleatorio entre 1 y el límite y lo muestre por pantalla indicando si es par o impar. Usar el operador ternario y la función [[https://www.php.net/manual/es/function.rand.php|rand]].
**Ejercicio 8**
Haz un programa en PHP que dado un dni nos calcule la letra. El cálculo de la letra se obtiene calculando el resto de la división del dni entre 23. Ese resto será la posición de la letra en la cadena
"TRWAGMYFPDXBNJZSQVHLCKEO". Usar la función [[https://www.php.net/manual/es/function.substr|substr]].
**Ejercicio 9**
Dado un cierto valor numérico, imprimirlo con dos decimales separados por una coma, mostrando también los miles separados por puntos. Usar la función [[https://www.php.net/manual/es/function.number-format|number_format]].
**Ejercicio 10**
Crea un archivo llamado //ejercicio10a.html//. Dentro escribe el código HTML necesario para que haya un enlace a //ejercicio10b.php//. Ese enlace le deberá pasar por //GET// una variable llamada //var1// con valor 10 (el atributo href de la etiqueta a será //href="ejercicio10b.php?var1=10"//).
Dentro del archivo //ejercicio10b.php// deberás comprobar si existe la variable y mostrar su valor por pantalla o cero si no existe. Para eso utiliza el operador //fusión de null// y la variable predefinida //$_GET// (abre directamente //ejercicio10b.php// en el navegador para comprobar si te muestra el valor 0).