Control de flujo y funciones
Con tipos del capítulo 2, el siguiente paso es decidir (if, match) e iterar, y agrupar lógica en funciones con tipos. No es un catálogo de cada bucle: un ejemplo de pedidos en memoria basta para ver el patrón.
Documentación oficial: if, match (PHP 8), foreach, funciones, argumentos nombrados.
Condiciones
<?php
declare(strict_types=1);
$unidades = 4;
if ($unidades <= 0) {
$estado = 'invalido';
} elseif ($unidades < 10) {
$estado = 'stock-ok';
} else {
$estado = 'revisar-almacen';
}match es una expresión (devuelve valor), compara con === y no hace fall-through como switch. Tiene que ser exhaustivo (default o todos los casos):
$iva = match ($estado) {
'stock-ok' => 0.21,
'revisar-almacen' => 0.21,
'invalido' => 0.0,
default => throw new InvalidArgumentException($estado),
};Úsalo cuando mapeas un valor a otro. Para rangos con varias sentencias, if sigue siendo más claro.
Bucles
foreaches el habitual sobre arrays (capítulo 4).forcuando tienes índice numérico y un tope.whilecuando la condición no es “N elementos”, sino “hasta que pase X”.
<?php
$lineas = [
['sku' => 'CAM-01', 'unidades' => 2, 'precio' => 19.9],
['sku' => 'PANT-02', 'unidades' => 1, 'precio' => 39.0],
];
$total = 0.0;
foreach ($lineas as $linea) {
$total += $linea['unidades'] * $linea['precio'];
}Funciones tipadas
Parámetros y retorno se anotan igual que en el capítulo 2. Los opcionales van después de los obligatorios. Los argumentos nombrados (PHP 8) evitan huecos null intermedios:
<?php
declare(strict_types=1);
function importeLinea(int $unidades, float $precio, float $descuento = 0.0): float
{
$bruto = $unidades * $precio;
return $bruto * (1 - $descuento);
}
$a = importeLinea(2, 19.9);
$b = importeLinea(unidades: 1, precio: 39.0, descuento: 0.1);Funciones flecha (fn, PHP 7.4): una expresión, capturan variables del exterior por valor. Sirven para callbacks cortos (array_map en el capítulo 4), no para sustituir funciones de varias líneas.
$conIva = fn (float $neto): float => $neto * 1.21;
echo $conIva($a), "\n";Ejemplo que procesa las líneas (mismo fichero que importeLinea):
<?php
declare(strict_types=1);
$lineas = [
['sku' => 'CAM-01', 'unidades' => 2, 'precio' => 19.9],
['sku' => 'PANT-02', 'unidades' => 1, 'precio' => 39.0],
];
function importeLinea(int $unidades, float $precio, float $descuento = 0.0): float
{
$bruto = $unidades * $precio;
return $bruto * (1 - $descuento);
}
function totalPedido(array $lineas, float $descuento = 0.0): float
{
$suma = 0.0;
foreach ($lineas as $linea) {
$suma += importeLinea($linea['unidades'], $linea['precio']);
}
return $suma * (1 - $descuento);
}
echo totalPedido($lineas), "\n";El array no está tipado en runtime: las claves sku / unidades / precio las garantiza tu código (objetos en el capítulo 9).
Errores habituales
switchcon==y uncase '0'que captura0entero;matchno tiene ese problema.- Parámetros opcionales antes de los obligatorios.
- Funciones que solo hacen
echoy no devuelven nada: peor de probar. Devuelve; elechoqueda en el borde (CLI o plantilla). - Recursión o
while (true)sin salida.
Buenas prácticas
- Una función, una pregunta (
totalPedido, noprocesarTodo). declare(strict_types=1)en ficheros con firmas.match+defaultque falle alto si llega un estado imposible.- El detalle de transformar listas enteras (
array_map) es el capítulo 4.
Ejercicio
- Añade una línea al array
$lineasy recalculatotalPedido. - Sustituye el
ifde$estadopor unmatchsobre$unidades(elige umbrales). - Llama
importeLineasolo con argumentos nombrados.
Siguiente paso
Continúa con Arrays y manejo de datos.
