02 - PHP VI: Funciones

PHP, como cualquier lenguaje estructurado, permite modular el código mediante funciones.

En este tema veremos como definir funciones en PHP, como pasar argumentos a las funciones y como devolver valores.

Además, desde la versión 5.3.0 PHP permite utilizar funciones anónimas. Veremos qué son y como implementarlas

Por último, desde la versión 7.4.0 también permite las funciones flecha. Estas funciones nos permiten utilizar una sintaxis más concisa para las funciones anónimas.

Una función puede ser definida empleando una sintaxis como la siguiente:

function foo($arg_1, $arg_2, /* ..., */ $arg_n) {
    echo "Función de ejemplo.\n";
    return $valor_devuelto;
}

En primer lugar usamos la palabra reservada function seguido del nombre que queramos dar a nuestra función. A continuación, definimos la lista de argumentos separados por coma y encerrados entre paréntesis.

El código de la función irá encerrado entre llaves ({ }). Cualquier código PHP válido puede aparecer dentro de la función, incluso otras funciones y definiciones de clases. Para devolver valores, usaremos return.

Al contrario que otros lenguajes, en PHP no es necesario definir una función antes de que sea referenciada (excepto cuando ésta esté condicionalmente definida). Por lo tanto, el siguiente código es perfectamente válido.

bar(4);
function bar($numero) {
    echo $numero;
};

Podemos definir funciones dentro de otras funciones, pero para poder llamarlas necesitamos llamar antes a la función padre.

function foo() {
    function bar() {
        echo "Hola mundo";
    }
}
    
bar();

Si llamamos directamente a la función bar() como en el ejemplo anterior, PHP nos mostrará un error diciendo que la función no está definida.

Sin embargo, si llamamos antes a la función foo() (aunque no haga nada), PHP ya nos permitirá usar la función bar().

function foo() {
    function bar() {
        ºecho "Hola mundo";
    }
}
foo();
bar();

Los nombres de las funciones son insensibles a mayúsculas - minúsculas, aunque es una buena idea llamar a las funciones tal y como aparecen en sus declaraciones.

No se pueden redefinir funciones. Una vez definida una función, no podemos crear otra con el mismo nombre (ni siquiera con diferentes parámetros de entrada, con lo que en PHP no está permitido el polimorfismo de funciones).

PHP permite recursividad.

function recursividad($a) {
    if ($a < 20) {
        echo "$a\n";
        recursividad($a + 1);
    }
}

Cualquier información puede ser pasada a las funciones mediante la lista de argumentos, la cual es una lista de expresiones delimitadas por comas. Los argumentos son evaluados de izquierda a derecha.

Por defecto, los argumentos de las funciones son pasados por valor. Para hacer que un argumento a una función se pase por referencia, hay que anteponer al nombre del argumento un ampersand (&).

Por ejemplo, si ejecutamos el siguiente código en un navegador:

function anyadir_algo($cadena) {
    $cadena .= 'y algo más.';
}

$cad = 'Esto es una cadena, ';
anyadir_algo($cad);
echo $cad;

La salida será:

Ya que al pasar el argumento $cad a la función por valor, en realidad le estamos pasando una copia de la variable, no la variable en sí.

Si queremos pasar una referencia a la variable, deberemos definir la función de la siguiente forma:

function anyadir_algo(&$cadena) {
    $cadena .= 'y algo más.';
}

$cad = 'Esto es una cadena, ';
anyadir_algo($cad);
echo $cad;

Lo que hará que la variable $cad cambie su valor al ejecutarse la función.

Una función puede definir valores predeterminados para argumentos escalares como sigue:

function hacer_café($tipo = "capuchino") {
    return "Hacer una taza de $tipo.\n";
}

echo hacer_café(); //imprimirá "Hacer una taza de capuchino"
echo hacer_café(null); //imprimirá "Hacer una taza de "
echo hacer_café("espresso"); //imprimirá "Hacer una taza de espresso"

Las declaraciones de tipo permiten a las funciones requerir que los parámetros sean de cierto tipo durante una llamada. Si el valor dado es de un tipo incorrecto, se generará un error (en PHP 7 se lanzará una excepción TypeError).

Para especificar una declaración de tipo, debe anteponerse el nombre del tipo al nombre del parámetro. Se puede hacer que una declaración acepte valores null si el valor predeterminado del parámetro se establece a null o se antepone un interrogante (?) al tipo.

function foo(int $numero) {
    return $numero + 1;
}
echo foo(2);

function foo(?int $numero) {
    return $numero + 1;
}
echo foo(2);

function foo(int $numero) {
    return $numero + 1;
}
echo foo("Hola");

A partir de PHP 7 podemos usar declaración estricta de tipos. Por ejemplo, si definimos una función con un argumento de tipo string y le pasamos un integer, PHP convertirá ese entero en una cadena.

function foo(string $palabra) {
    echo "La palabra es $palabra";
}
foo(1); //imprimirá "La palabra es 1"

Pero podemos habilitar el modo estricto en el fichero añadiendo la línea declare(strict_types=1);.

declare(strict_types=1);

function foo(string $palabra) {
    echo "La palabra es $palabra";
}
foo(1);

Con lo que, ahora sí, PHP nos mostraría el error correspondiente.

PHP tiene soporte para lista de argumentos de longitud variable en funciones definidas por el usuario. Esto se implementa utilizando el token en PHP 5.6 y posteriores. Los argumentos serán pasados a la función como un array.

function suma(...$numeros) {
    $resultado = 0;
    foreach ($numeros as $n) {
        $resultado += $n;
    }
    return "El resultado es $resultado<br>";
}
echo suma(2, 5); //imprimirá "El resultado es 7"
echo suma(1, 2, 3, 4); //imprimirá "El resultado es 10"

Se puede especificar argumentos normales antes del token . En este caso, solamente los argumentos al final que no coincidan con un argumento posicional serán añadidos al array generado por .

También es posible añadir una declaración de tipo antes del símbolo . Si está presente, todos los argumentos capturados por deben ser objetos de la clase implicada.

function suma(string $cadena, int ...$numeros) {
    $resultado = 0;
    foreach ($numeros as $n) {
        $resultado += $n;
    }
    return "$cadena $resultado<br>";
}
echo suma("El resultado es ", 5, 8, 7);
echo suma("La suma es ", 5, 8, 7);

Los valores son devueltos usando la sentencia opcional return. Se puede devolver cualquier tipo, incluidos arrays y objetos. Ésto causa que la función finalice su ejecución inmediatamente y pase el control de nuevo a la línea desde la que fue llamada. Si se omite return el valor devuelto será null.

PHP 7 añade soporte para las declaraciones de tipo de devolución. De forma similar a las declaraciones de tipo de argumento, las declaraciones de tipo de devolución especifican el tipo del valor que será devuelto desde una función.

function sum($a, $b): float {
    return $a + $b;
}
$resultado = sum(1, 2);
echo "El resultado es $resultado";
var_dump($resultado);

Si nos fijamos en el resultado, aunque parezca que la función devuelve un entero con var_dump vemos que lo que realmente está devolviendo es un float.

PHP admite el concepto de funciones variables. Esto significa que si un nombre de variable tiene paréntesis anexos a él, PHP buscará una función con el mismo nombre que lo evaluado por la variable, e intentará ejecutarla.

Entre otras cosas, esto se puede usar para implementar llamadas de retorno, tablas de funciones, y así sucesivamente.

function foo() {
    echo "En foo()<br>";
}
function bar($arg = '') {
    echo "En bar(); el argumento era '$arg'.<br>";
}
function hacerecho($cadena) {
    echo $cadena;
}

$func = 'foo';
$func(); // Esto llama a foo()
$func = 'bar';
$func('prueba'); // Esto llama a bar()
$func = 'hacerecho';
$func('prueba'); // Esto llama a hacerecho()

A partir de PHP 5.3.0, las funciones anónimas, también conocidas como cierres (closures), permiten la creación de funciones que no tienen un nombre especificado. Son más útiles como valor de los parámetros de callbacks, pero tienen muchos otros usos.

Por ejemplo, vamos a utilizar la función uasort de PHP, la cual ordena un array con una función de comparación definida por el usuario y mantiene la asociación de índices.

function cmp($a, $b) {
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}

$array = [
    'a' => 4,
    'b' => 8,
    'c' => -1,
    'd' => -9,
    'e' => 2,
    'f' => 5,
    'g' => 3,
    'h' => -4
];
uasort($array, 'cmp');
var_dump($array);

Podríamos utilizar una función anónima para mejorar la organización y aumentar la legibilidad del código.

$array = [
    'a' => 4,
    'b' => 8,
    'c' => -1,
    'd' => -9,
    'e' => 2,
    'f' => 5,
    'g' => 3,
    'h' => -4
];
uasort($array, function ($val1, $val2) {
    return $val1 == $val2 ? 0 : ($val1 < $val2 ? -1 : 1);
});
var_dump($array);

Las funciones anónimas también se pueden usar como valores de variables. La asignación de un función anónima a una variable emplea la misma sintaxis que cualquier otra asignación, incluido el punto y coma final:

$saludo = function($nombre) {
    echo"Hola $nombre<br>";
};
$saludo('Mundo');
$saludo('PHP');

Para acceder a variables globales dentro de las funciones anónimas, utilizamos la palabra reservada use.

$empezar = "Hola ";
$saludo = function($nombre) use($empezar) {
    echo"$empezar$nombre<br>";
};
$saludo('Mundo');
$saludo('PHP');

Las funciones de flecha fueron introducidas en PHP 7.4 como una sintaxis más concisa para las funciones anónimas.

Las funciones de flecha tienen la forma básica fn (lista de argumentos) ⇒ expresión.

$suma = fn($x, $y) => $x + $y;
$resultado = $suma(2, 3);
echo "El resultado es $resultado";

Las funciones de flecha sólo permiten una expresión, lo que significa que no pueden contener varias líneas de código. Es por eso que se omiten las llaves de inicio y final de función y la palabra reservada return.

El ejemplo anterior usando funciones anónimas es equivalente a:

$suma = function($x, $y) {
    return $x + $y;
};
$resultado = $suma(2, 3);
echo "El resultado es $resultado";

Ejercicio 1

Crea una función en PHP que sume dos números que se le pasarán como argumentos.

Ejercicio 2

Modifica el ejercicio anterior para que uno de los números esté almacenado en una variable fuera de la función.

Ejercicio 3

Dado el siguiente array:

$miArray = [3, 4, 6];

Crea una función en PHP que añada un elemento al array. A dicha función se le pasará el array y el elemento a insertar como argumentos.

Ejercicio 4

Crea una función en PHP que muestre por pantalla la frase que se le pase como argumento o el string “Hola mundo” si no se le pasa ninguna.

Ejercicio 5

Crea una función PHP donde se le pasarán 1 argumento de tipo string y la mostrará por pantalla. La función mostrará un error en el caso que el argumento no sea una cadena.

Ejercicio 6

Crea una función PHP que multiplique los números que se le pasen. A la función se le pueden pasar diferente cantidad de números (2, 3, 5…) y deberá multiplicarlos todos.

Ejercicio 7

Crea una función PHP donde se le pasarán 3 argumento. El primer argumento será de tipo int. El segundo será un array numérico. El tercero será una serie de números que tendremos que sumar al primer argumento.

El resultado lo añadiremos como un nuevo elemento al array. La función deberá comprobar que los tipos de datos son correctos.

Ejercicio 8

Crea una función anónima que devuelva la multiplicación de dos números. Asignar esa función a una variable y ejecutarla para comprobar el resultado.

Ejercicio 9

Modificar el ejercicio anterior para utilizar una función flecha.

  • clase/daw/dws_php/1eval/php_funciones.txt
  • Última modificación: 2023/07/10 11:19
  • por cesguiro