Programación modular (funciones)¶
En PHP, cuando no se declaran tipos de datos, los parámetros de las funciones no tienen un tipo específico, y tampoco se indica el tipo de dato que devuelve la función. Los parámetros se pasan por valor, lo que significa que se hace una copia de la variable y cualquier modificación dentro de la función no afecta la variable original.
<?php
function nombreFuncion($par1, $par2, ...) {
// código
return $valor;
}
$resultado = nombreFuncion($arg1, $arg2, …);
?>
Por ejemplo:
<?php
function diaSemana() {
$semana = [ "lunes", "martes", "miércoles",
"jueves", "viernes", "sábado", "domingo" ];
$dia = $semana[rand(0, 6)];
return $dia;
}
$diaCine = diaSemana();
echo "El próximo $diaCine voy al cine.";
?>
El próximo lunes voy al cine.
Parámetros¶
Parámetros por referencia¶
Si queremos pasar un parámetro por referencia (de modo que los cambios en la función afecten a la variable original), usamos el operador &
delante del parámetro en la declaración de la función. Así, se pasa la dirección de memoria de la variable.
<?php
function duplicarPorValor($argumento) {
$argumento = $argumento * 2;
echo "Dentro de la función: $argumento.<br>";
}
function duplicarPorReferencia(&$argumento) {
$argumento = $argumento * 2;
echo "Dentro de la función: $argumento.<br>";
}
$numero1 = 5;
echo "Antes de llamar: $numero1.<br>";
duplicarPorValor($numero1);
echo "Después de llamar: $numero1.<br>";
echo "<br>";
$numero2 = 7;
echo "Antes de llamar: $numero2.<br>";
duplicarPorReferencia($numero2);
echo "Después de llamar: $numero2.<br>";
?>
Parámetros por defecto u opcionales¶
Podemos asignar valores por defecto a los parámetros en la declaración de la función. Si no se proporciona un argumento al llamar a la función, se usará el valor por defecto.
<?php
function obtenerCapital($pais = "todos") {
$capitales = array("Italia" => "Roma",
"Francia" => "Paris",
"Portugal" => "Lisboa");
if ($pais == "todos") {
return array_values($capitales);
} else {
return $capitales[$pais];
}
}
print_r(obtenerCapital()); // Devuelve todas las capitales
echo "<br/>";
echo obtenerCapital("Francia"); // Devuelve "París"
Cuando se combinan con otros parámetros, los parámetros opcionales deben colocarse al final.
<?php
function saluda($nombre, $prefijo = "Sr") {
echo "Hola ".$prefijo." ".$nombre;
}
saluda("Ginés", "Mr");
saluda("López");
saluda("Lola", "Srta");
Parámetros variables¶
Podemos crear funciones donde no se defina de antemano la cantidad de parámetros. Para gestionar estos parámetros variables, PHP ofrece varias funciones útiles:
func_get_args()
: Obtiene un array con todos los parámetros recibidos.func_num_args()
: Obtiene la cantidad de parámetros pasados.func_get_arg(numArgumento)
: Obtiene el valor del argumento en la posiciónnumArgumento
.
<?php
function sumaParametros() {
if (func_num_args() == 0) {
return false;
} else {
$suma = 0;
for ($i = 0; $i < func_num_args(); $i++) {
$suma += func_get_arg($i);
}
return $suma;
}
}
echo sumaParametros(1, 5, 9); // 15
?>
Desde PHP 5.6, se puede utilizar el operador ...
(variadics), que convierte automáticamente los parámetros en un array.
<?php
function sumaParametrosMejor(...$numeros) {
if (count($numeros) == 0) {
return false;
} else {
$suma = 0;
foreach ($numeros as $num) {
$suma += $num;
}
return $suma;
}
}
echo sumaParametrosMejor(1, 5, 9); // 15
?>
Más usos de ...
También se puede utilizar el operador ...
para expandir un array en variables separadas cuando se llama a una función.
<?php
function suma($a, $b) {
return $a + $b;
}
echo suma(...[1, 5])."<br />"; // 6
$a = [1, 5];
echo suma(...$a); // 6
?>
Argumentos con nombre¶
Desde PHP 8.0, es posible pasar parámetros utilizando el nombre del argumento, además de su posición habitual.
<?php
function funcionArgumentosNombre($a, $b = 2, $c = 4) {
echo "$a $b $c";
}
funcionArgumentosNombre(c: 3, a: 1); // "1 2 3"
Los parámetros opcionales y obligatorios pueden tener nombres, pero los argumentos con nombre deben aparecer después de los que se pasan por posición.
<?php
funcionArgumentosNombre(1, c: 3); // "1 2 3"
funcionArgumentosNombre(c: 3, 1); // "Error"
Funciones tipadas¶
Desde PHP 7, es posible definir los tipos de los parámetros y el valor de retorno de las funciones. Esto se conoce como tipificación estricta (strict types) y se activa con la declaración declare(strict_types=1);
en la primera línea del archivo.
<?php
declare(strict_types=1);
function suma(int $a, int $b) : int {
return $a + $b;
}
$num = 33;
echo suma(10, 30);
echo suma(10, $num);
echo suma("10", 30); // error por tipificación estricta, sino daría 40
?>
Alcance o scope¶
Las variables definidas fuera de las funciones tienen un alcance global y pueden accederse desde cualquier lugar, excepto desde dentro de las funciones (a menos que se declaren globales explícitamente). Las variables declaradas dentro de una función tienen un alcance local y sólo son accesibles desde dentro de esa función.
<?php
function miCiudad() {
$ciudad = "Elche";
echo "Dentro de la función: $ciudad.<br>"; // Dentro de la función: Elche.
}
$ciudad = "Alicante";
echo "Antes de la función: $ciudad.<br>"; // Antes de la función: Alicante.
miCiudad();
echo "Después de la función: $ciudad.<br>"; // Después de la función: Alicante.
?>
<?php
function miCiudad() {
global $ciudad;
$ciudad = "Elche";
echo "Dentro de la función: $ciudad.<br>"; // Dentro de la función: Elche.
}
$ciudad = "Alicante";
echo "Antes de llamar: $ciudad.<br>"; // Antes de la función: Alicante.
miCiudad();
echo "Después de llamar: $ciudad.<br>" // Después de la función: Elche.
?>
Evitar variables globales
Es preferible no utilizar variables globales dentro de las funciones. Si es necesario, se recomienda pasarlas como parámetro.
Funciones variable¶
En PHP, se pueden asignar funciones a variables y llamarlas a través de la variable.
<?php
$miFuncionSuma = "suma";
echo $miFuncionSuma(3,4); // invoca a la función suma
?>
Funciones anónimas¶
PHP también admite funciones anónimas (sin nombre), útiles para callbacks. Se pueden usar como cualquier otra variable.
<?php
$anonima = function() {
echo "Hola";
};
$anonima();
$anonimaConParametro = function($nombre) {
echo "Hola ".$nombre;
};
$anonimaConParametro("Ginés");
// Uso de variables externas a la función anónima --> `use`
$mensaje = "Hola";
$miClosure = function() use ($mensaje) {
echo $mensaje;
};
$miClosure();
// Uso de parámetros
$holaPHP = function($arg) use ($mensaje) {
echo $mensaje." ".$arg;
};
$holaPHP("PHP");
?>
Desde PHP 7.4, se han introducido las funciones flecha (arrow functions) para simplificar su uso.
Biblioteca de funciones¶
Podemos agrupar funciones en archivos separados para reutilizarlas en otros programas usando include
o require
. Por ejemplo:
<?php
function suma(int $a, int $b) : int {
return $a + $b;
}
function resta(int $a, int $b) : int {
return $a - $b;
}
?>
<?php
include_once("biblioteca.php");
echo suma(10,20);
echo resta(40,20);
?>
require
lanza un error fatal, include
lo ignora. Las funciones _once
sólo se cargan una vez, si ya ha sido incluida previamente, no lo vuelve a hacer, evitando bucles.
Plantillas mediante include
¶
Podemos usar include para separar fragmentos de código y crear plantillas reutilizables.
¿Qué es una vista en el patrón MVC?
En el patrón Modelo-Vista-Controlador (MVC), la vista es la parte de la aplicación encargada de mostrar la información al usuario.
Su función principal es representar los datos del modelo de forma visual (por ejemplo, en una página HTML) y permitir que el usuario interactúe con la interfaz.
Las vistas no contienen lógica de negocio ni manipulan directamente los datos: simplemente presentan lo que el controlador les proporciona.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $titulo ?></title>
</head>
<body>
La parte de abajo, por ejemplo, solo va a contener HTML y la colocamos en pie.html
:
<footer>Ginés López</footer>
</body>
</html>
Y luego nos centramos únicamente en el contenido que cambia en pagina.php
:
<?php
$titulo = "Página con includes";
include("encabezado.php");
?>
<h1><?= $titulo ?></h1>
<?php
include("pie.html");
?>
Diferencias entre include, include_once, require y require_once en PHP
En PHP, estos cuatro comandos se usan para incluir archivos externos, pero hay algunas diferencias clave entre ellos:
include
yrequire
hacen básicamente lo mismo: insertan el contenido de un archivo en el script.- La diferencia está en cómo manejan los errores:
include
lanza una advertencia (warning) si el archivo no se encuentra, pero el script sigue ejecutándose.require
lanza un error fatal (fatal error) si el archivo no se encuentra, y el script se detiene.include_once
yrequire_once
funcionan igual que sus versiones normales, pero evitan que el mismo archivo se incluya más de una vez, lo cual es útil para prevenir errores de redefinición de funciones o clases.
Ejemplos:
// include: lanza warning si el archivo no existe, pero continúa la ejecución
include 'archivo.php';
// include_once: igual que include, pero no vuelve a incluir el archivo si ya fue incluido
include_once 'archivo.php';
// require: lanza error fatal si el archivo no existe y detiene el script
require 'archivo.php';
// require_once: igual que require, pero evita incluir el archivo más de una vez
require_once 'archivo.php';
💡 Recomendación: en general, require_once
es una buena práctica para incluir archivos que solo deben cargarse una vez, como archivos de configuración, clases o funciones comunes.
Actividades¶
-
AC 214. (RA3 / CE3a CE3b CE3d / IC1 / 3p) El CTO solicita crear una librería de funciones que incluya las siguientes implementaciones:
- Una función que averigüe si un número es par:
esPar(int $num): bool
- Una función que devuelva un array de tamaño $tam con números aleatorios comprendido entre
$min
y$max
:arrayAleatorio(int $tam, int $min, int $max) : array
- Una función que reciba un $array por referencia y devuelva la cantidad de números pares que hay almacenados:
arrayPares(array &$array): int
La librería se ha de nombrar
libreria-XYZ.php
, siendoXYZ
las siglas de tu nombre. - Una función que averigüe si un número es par:
-
AC 215. (RA3 / CE3a CE3b CE3d / IC1 / 3p) Es necesario expandir la librería con las siguientes funciones adicionales:
digitos(int $num): int
: Devuelve la cantidad de dígitos de un número.digitoN(int $num, int $pos): int
: Devuelve el dígito que ocupa, empezando por la izquierda, la posición$pos
.quitaPorDetras(int $num, int $cant): int
: Le quita por detrás (derecha)$cant
dígitos.quitaPorDelante(int $num, int $cant): int
: Le quita por delante (izquierda)$cant
dígitos.
-
PR 216. (RA3 / CE3a CE3b CE3d CE3g / IC2 / 5p) Desde Docentes Asociados S.A se solicita implementar una lógica de compra, en la cual, tras solicitar una cantidad de productos, se lean los nombres y precios de los mismos. Tras ingresar esta información, se debe crear una tabla que muestre los productos con su precio en euros y dólares, además de un totalizador en ambas monedas.
-
PR 217. (RA3 / CE3a CE3b CE3d CE3g / IC2 / 5p) Siguiendo con la actividad anterior, se requiere la creación de una plantilla utilizando
includes
, que contenga:- Un encabezado que muestre "Supermercado Asociado" en un elemento
h1
. - Un pie que contenga el texto "Tu supermercado de confianza".
- Un archivo que incluya tanto el encabezado como el pie, encargado de preparar la compra.
- Otro archivo que también incluya encabezado y pie, dedicado a imprimir el ticket de compra.
- Un encabezado que muestre "Supermercado Asociado" en un elemento