Una función es un grupo de instrucciones, independiente del programa principal, que se puede reutilizar a lo largo de un programa. Las funciones nos ahorran tener que repetir el grupo de instrucciones, sustituyéndolos por simples llamadas a las funciones.
En esta lección se tratan primero las funciones sin argumentos y después las funciones con argumentos. Todo lo que se comenta sobre las funciones sin argumentos (forma de definirlas, nombre, etc.) se aplica también a las funciones con argumentos.
Las funciones se identifican por su nombre. Las funciones se definen mediante la palabra reservada function seguida del nombre de la función y unos paréntesis, seguidos de un conjunto de instrucciones escritos entre llaves. La llave que abre el bloque de instrucciones se suele escribir al principio de la línea siguiente, no a continuación del nombre de la función.
function nombreDelaFuncion()
{
bloque_de_sentencias
}
Las funciones se aprovechan en el resto del programa escribiendo el nombre de la función seguido de paréntesis. PHP ejecuta el bloque de instrucciones de la función cada vez que se llama a la función.
<?php
// Definición de la función prueba()
function prueba()
{
print "<p>I will not waste chalk.</p>\n";
print "\n";
print "<p>I will not skateboard in the halls.</p>\n";
print "\n";
print "<p>I will not burp in class.</p>\n";
print "\n";
}
print "<p>Programa de prueba.</p>\n";
print "\n";
// Llamadas a la función prueba()
prueba();
prueba();
?>
<p>Programa de prueba.</p>
<p>I will not waste chalk.</p>
<p>I will not skateboard in the halls.</p>
<p>I will not burp in class.</p>
<p>I will not waste chalk.</p>
<p>I will not skateboard in the halls.</p>
<p>I will not burp in class.</p>
<?php
// Definición de la función prueba()
function prueba()
{
print "<p>¡Hola!</p>\n";
}
// Llamada a la función prueba()
prueba();
?>
<p>¡Hola!</p>
<?php
// Llamada a la función prueba()
prueba();
// Definición de la función prueba()
function prueba()
{
print "<p>¡Hola!</p>\n";
}
?>
<p>¡Hola!</p>
Los nombres de las funciones siguen las mismas reglas de los identificadores de PHP, es decir, deben comenzar por una letra o un guion bajo (_) y el resto de caracteres pueden ser letras, números o guiones bajos (se pueden utilizar caracteres no ingleses como acentos, eñes, etc), pero los nombres de funciones no distinguen entre mayúsculas o minúsculas.
La guía de estilo PEAR para PHP recomienda que los nombres de las funciones sigan el estilo camelCase (es decir, sin espacios ni guiones, con la primera palabra en minúsculas y el resto con la primera letra en mayúsculas).
<?php
// Definición de la función prueba()
function prueba()
{
print "<p>I will not waste chalk.</p>\n";
print "\n";
print "<p>I will not skateboard in the halls.</p>\n";
print "\n";
print "<p>I will not burp in class.</p>\n";
print "\n";
}
print "<p>Programa de prueba.</p>\n";
?>
<p>Programa de prueba.</p>
<?php
// Definición de la función prueba()
function prueba()
{
print "<p>I will not waste chalk.</p>\n";
print "\n";
}
// Llamadas a la función prueba()
prueba();
PRUEBA();
PrUeBa();
?>
<p>I will not waste chalk.</p>
<p>I will not waste chalk.</p>
<p>I will not waste chalk.</p>
<?php
function prueba()
{
print "<p>¡Hola!</p>\n";
}
function prueba()
{
print "<p>¡Adios!</p>\n";
}
?>
Fatal error: Cannot redeclare prueba() (previously declared in ejemplo.php:4) in ejemplo.php on line 7
<?php
function prueba()
{
print "<p>¡Hola!</p>\n";
}
function Prueba()
{
print "<p>¡Adios!</p>\n";
}
?>
Fatal error: Cannot redeclare Prueba() (previously declared in ejemplo.php:4) in ejemplo.php on line 7
Las funciones son independientes del resto del programa. En particular, las variables que aparecen en una función son independientes de las variables del programa principal. En principio, ni la función tiene acceso a las variables del programa principal, ni el programa principal tiene acceso a las variables de la función.
<?php
// Definición de la función prueba()
function prueba()
{
$a = 42;
print "<p>En la función, la variable a es $a.</p>\n";
print "\n";
}
// Damos un valor a la variable
$a = 100;
print "<p>En el programa principal, la variable a es $a.</p>\n";
print "\n";
// Llamamos a la función, que da un valor distinto a una variable con el mismo nombre
prueba();
// Pero en el programa principal, la variable no ha cambiado su valor
print "<p>En el programa principal, la variable a es $a.</p>\n";
?>
<p>En el programa principal, la variable a es 100.</p>
<p>En la función, la variable a es 42.</p>
<p>En el programa principal, la variable a es 100.</p>
<?php
// Definición de la función prueba()
function prueba()
{
// Intentamos escribir el valor de la variable $a
// pero como no está definida, se produce un aviso
print "<p>En la función, la variable a es $a.</p>\n";
print "\n";
}
// Damos un valor a la variable
$a = 100;
print "<p>En el programa principal, la variable a es $a.</p>\n";
print "\n";
// Llamamos a la función
prueba();
// Volvemos a escribir la variable
print "<p>En el programa principal, la variable a es $a.</p>\n";
?>
<p>Programa de prueba.</p>
<p>En el programa principal, la variable a es 100.</p>
<br />
<b>Warning</b>: Undefined variable $a in <b>ejemplo.php</b> on line <b>7</b><br />
<p>En la función, la variable a es .</p>
<p>En el programa principal, la variable a es 100.</p>
<?php
// Definición de la función prueba()
function prueba()
{
// La variable $a sólo está definida en la función, no fuera de ella
$a = 42;
print "<p>En la función, la variable a es $a.</p>\n";
print "\n";
}
// Llamamos a la función
prueba();
// Intentamos escribir el valor de la variable $a
// pero como no está definida, se produce un aviso
print "<p>En el programa principal, la variable a es $a.</p>\n";
?>
<p>En la función, la variable a es 42.</p>
<br />
<b>Warning</b>: Undefined variable $a in <b>ejemplo.php</b> on line <b>16</b><br />
<p>En el programa principal, la variable a es .</p>
Podemos hacer que una función tenga acceso a las variables del programa principal, indicando en el cuerpo de la función los nombres de las variables precedidas de la palabra reservada global.
<?php
function prueba()
{
// Declaramos la variable $a como global
global $a;
print "<p>En la función, la variable a es $a.</p>\n";
print "\n";
}
$a = 100;
prueba();
?>
<p>En la función, la variable a es 100.</p>
<?php
function prueba()
{
global $a;
// Modificamos la variable $a en la función
$a = 50;
}
$a = 100;
print "<p>En el programa principal, la variable a es $a.</p>\n";
prueba();
print "<p>En el programa principal, la variable a es $a.</p>\n";
?>
<p>En el programa principal, la variable a es 100.</p>
<p>En el programa principal, la variable a es 50.</p>
Podemos enviar datos a una función incluyendo argumentos en su llamada. En la definición de la función deben indicarse los argumentos que se van a recibir, escribiéndolos entre los paréntesis como variables, separadas por comas. En el programa principal, los datos que se quieren enviar a la función simplemente se incluyen en la llamada a la función escribiéndolos entre los paréntesis, separados por comas. La función guarda los valores en los argumentos (como variables) en el orden indicado en la definición (salvo si se utiliza en la llamada a la función la notación de argumentos con nombre). Los argumentos se pueden utilizar o no en la función, pero si una función se define con argumentos, la llamada a la función debe incluir todos los argumentos indicados en la definición (salvo si en la definición de la función se indican valores predeterminados de los argumentos).
function nombreDelaFuncion($argumento_1, $argumento_2, etc ...) {
bloque_de_sentencias
}
En este apartado se trata el caso más sencillo, es decir, cuando los argumentos son simplemente valores (número, cadenas, matrices, etc.). En los dos apartados siguientes se tratan los casos en los que los argumentos son variables del programa principal.
<?php
function saludo($nombre)
{
print "<p>¡Hola, $nombre!</p>\n";
print "\n";
}
saludo("Don Pepito");
saludo("Don José");
?>
<p>¡Hola, Don Pepito!</p>
<p>¡Hola, Don José!</p>
<?php
function saludo($nombre, $veces)
{
for ($i = 0; $i < $veces; $i++) {
print "<p>¡Hola, $nombre!</p>\n";
print "\n";
}
}
saludo("Don Pepito", 3);
?>
<p>¡Hola, Don Pepito!</p>
<p>¡Hola, Don Pepito!</p>
<p>¡Hola, Don Pepito!</p>
<?php
// Definición de la función prueba($x) con 1 argumento
function prueba($x)
{
// Esta función no hace nada
}
// LLamamos a la función sin enviar el argumento
prueba();
?>
Fatal error: Uncaught ArgumentCountError: Too few arguments to function prueba(), 0 passed in ejemplo.php on line 9 and exactly 1 expected in ejemplo.php:3
Stack trace:
#0 ejemplo.php(9): prueba()
#1 {main}
thrown in ejemplo.php on line 3
<?php
function saludo($nombre)
{
print "<p>¡Hola, $nombre!</p>\n";
}
saludo("Don Pepito", "Don José");
?>
<p>¡Hola, Don Pepito</p>
<?php
function saludo()
{
print "<p>¡Hola!</p>\n";
}
saludo("Don Pepito");
?>
<p>Hola</p>
Cuando llamamos a una función escribiendo como argumento una variable del programa principal, lo único que se envía es el valor de la variable. En programación está situación se suele llamar "paso por valor".
<?php
// Definición de la función prueba()
function prueba($x)
{
print "<p>En la función, la variable recibida es $x.</p>\n";
print "\n";
}
// Damos un valor a las variables
$a = 100;
$b = 50;
// Escribimos el valor de las variables
print "<p>En el programa principal, la variable a es $a y la variable b es $b.</p>\n";
print "\n";
// Llamamos a la función
prueba($a);
prueba($b);
// Volvemos a escribir las variables
print "<p>En el programa principal, la variable a es $a y la variable b es $b.</p>\n";
?>
<p>En el programa principal, la variable a es 100 y la variable b es 50.</p>
<p>En la función, la variable recibida es 100.</p>
<p>En la función, la variable recibida es 50.</p>
<p>En el programa principal, la variable a es 100 y la variable b es 50.</p>
<?php
function prueba($x)
{
$x = 200;
print "<p>En la función, la variable x es $x.</p>\n";
print "\n";
}
$a = 100;
print "<p>En el programa principal, la variable a es $a.</p>\n";
print "\n";
prueba($a);
print "<p>En el programa principal, la variable a es $a.</p>\n";
?>
<p>En el programa principal, la variable a es 100.</p>
<p>En la función, la variable x es 200.</p>
<p>En el programa principal, la variable a es 100.</p>
<?php
function saludo($nombre)
{
$nombre = "desconocido";
print "<p>(función) ¡Hola, $nombre!</p>\n";
print "\n";
}
$nombre = "Don Pepito";
saludo($nombre);
print "<p>(programa principal) ¡Hola, $nombre!</p>\n";
?>
<p>(función) ¡Hola, desconocido!</p>
<p>(programa principal) ¡Hola, Don Pepito!</p>
Utilizando la notación del "paso por referencia", la función puede tener acceso a la variable del programa principal (no únicamente a su valor como ocurre en el paso por valor).
<?php
function prueba(&$x)
{
$x = 200;
print "<p>En la función, la variable x es $x.</p>\n";
print "\n";
}
$a = 100;
print "<p>En el programa principal, la variable a es $a.</p>\n";
print "\n";
prueba($a);
print "<p>En el programa principal, la variable a es $a.</p>\n";
?>
<p>En el programa principal, la variable a es 100.</p>
<p>En la función, la variable x es 200.</p>
<p>En el programa principal, la variable a es 200.</p>
Al declarar una función, podemos indicar el tipo de los argumentos. De esta manera, al llamar a la función en un programa, PHP puede detectar si el tipo de los argumentos es incorrecto y mostrar el error fatal correspondiente.
<?php
function suma(float $x, float $y)
{
return $x + $y;
}
print suma(5, "abc");
?>
Fatal error: Uncaught TypeError: suma(): Argument #2 ($y) must be of type float, string given, called in prueba.php on line 6 and defined in prueba:2
Stack trace:
#0 prueba.php(6): suma(5.0, 'abc')
#1 {main}
thrown in prueba.php on line 2
Algunos de los tipos que se pueden indicar son los tipos boolean, int, float, string o array.
Si un argumento puede ser de varios tipos, se debe indicar como una expresión lógica de los tipos (utilizando el operador lógico |), como muestra el siguiente ejemplo.
<?php
function printea(int|float|string|array $x)
{
if (is_array($x) ) {
print "<pre>\n";
print_r($x);
print "</pre>\n";
} else {
print($x);
}
}
printea("<p>Hola</p>\n");
printea("\n");
printea([1, 2]);
?>
<p>Hola</p>
<pre>
Array
(
[0] => 1
[1] => 2
)
</pre>
Para indicar que un argumento puede ser de cualquier tipo, se puede indicar con el tipo mixed.
De la misma manera que el programa principal puede enviar valores a una función, una función puede devolver uno o varios valores al programa principal. La palabra reservada return permite indicar la variable que se devuelve.
<?php
function suma($arg1, $arg2)
{
return $arg1 + $arg2;
}
$a = 20;
$b = 30;
// Podemos guardar el dato devuelto por la función en una variable ...
$suma = suma($a, $b);
// ... y mostrar su valor
print "<p>$a + $b = $suma</p>\n";
print "\n";
// También podemos mostrar el valor directamente ...
print "<p>$a + $b = " . suma($a, $b) . "</p>\n";
?>
<p>20 + 30 = 50</p>
<p>20 + 30 = 50</p>
<?php
function suma($arg1, $arg2)
{
return $arg1 + $arg2;
// Esta instrucción no se ejecuta nunca.
print "<p>Hola</p>\n";
}
$a = 20;
$b = 30;
print "<p>$a + $b = " . suma($a, $b) . "</p>\n";
?>
<p>20 + 30 = 50</p>
<?php
function sumaProducto($arg1, $arg2)
{
return [$arg1 + $arg2, $arg1 * $arg2];
}
$a = 20;
$b = 30;
// Podemos guardar el dato devuelto por la función en una variable (que será de tipo matriz) ...
$sp = sumaProducto($a, $b);
// ... y mostrar los valores
print "<p>$a + $b = $sp[0]</p>\n";
print "\n";
print "<p>$a * $b = $sp[1]</p>\n";
print "\n";
// También podemos mostrar los valores directamente (teniendo en cuenta que es una matriz) ...
print "<p>$a + $b = " . sumaProducto($a, $b)[0] . "</p>\n";
print "\n";
print "<p>$a * $b = " . sumaProducto($a, $b)[1] . "</p>\n";
print "\n";
?>
<p>20 + 30 = 50</p>
<p>20 * 30 = 600</p>
<p>20 + 30 = 50</p>
<p>20 * 30 = 600</p>
Desde PHP 7.1 (publicado en diciembre de 2016) los valores de la matriz devuelta por una función se pueden recoger directamente en varias variables utilizando corchetes. Técnicamente, esta operación se denomina desestructurar la matriz y en versiones anteriores se debía hacer con la construcción del lenguaje list().
<?php
function sumaProducto($arg1, $arg2)
{
return [$arg1 + $arg2, $arg1 * $arg2];
}
$a = 20;
$b = 30;
[$suma, $producto] = sumaProducto($a, $b);
print "<p>$a + $b = $suma</p>\n";
print "\n";
print "<p>$a * $b = $producto</p>\n";
?>
<p>20 + 30 = 50</p>
<p>20 * 30 = 600</p>
Al declarar una función, podemos indicar el tipo del valor devuelto por la función escribiendo : (dos puntos) y el tipo al final de la línea de definición de la función.
function nombreDelaFuncion(): tipoDevuelto
{
bloque_de_sentencias
}
De esta manera, al llamar a la función en un programa, PHP puede detectar si el tipo del valor devuelto es incorrecto y mostrar el error fatal correspondiente.
<?php
function une($x, $y): float
{
return $x . $y;
}
print "<p>" . une(6.5, 6) . "</p>\n";
print "\n";
print "<p>" . une(6.5, 6.5) . "</p>\n";
?>
6.56
Fatal error: Uncaught TypeError: une(): Return value must be of type float, string returned in prueba.php:4
Stack trace:
#0 prueba.php(8): une(6.5, 6.5)
#1 {main}
thrown in prueba.php on line 4
Algunos de los tipos que se pueden indicar son los tipos boolean, int, float, string o array.
Si el dato devuelto puede ser de varios tipos, se debe indicar como una expresión lógica de los tipos (utilizando el operador lógico |), como muestra el siguiente ejemplo.
<?php
function une($x, $y): float|string
{
return $x . $y;
}
print "<p>" . une(6.5, 6) . "</p>\n";
print "\n";
print "<p>" . une(6.5, 6.5) . "</p>\n";
?>
<p>6.56</p>
<p>6.56.5</p>
Si el dato devuelto puede ser de cualquier tipo, se debe indicar con el tipo mixed.
Si una función no devuelve ningún dato, se puede indicar con el tipo void.
En PHP se pueden definir funciones con argumentos predeterminados, de manera que si en la llamada a la función no se envía un argumento, la función asume un valor predeterminado.
Los argumentos predeterminados se establecen en la definición de la función, igualando el nombre del argumento a su valor predeterminado.
El ejemplo siguiente muestra una función que calcula diferentes tipos de media (aritmética, geométrica, armónica). Los argumentos de la función son los números cuya media se debe calcular y el tipo de media a calcular. En el ejemplo, el tipo de media predeterminado es la media aritmética.
<?php
// ESTA ES LA DEFINICIÓN DE LA FUNCIÓN calculaMedia
function calculaMedia($arg1, $arg2, $arg3 = "aritmética")
{
if ($arg3 == "aritmética") {
$media = ($arg1 + $arg2) / 2;
} elseif ($arg3 == "geométrica") {
$media = sqrt($arg1 * $arg2) / 2;
} elseif ($arg3 == "armónica") {
$media = 2 * ($arg1 * $arg2) / ($arg1 + $arg2);
}
return $media;
}
// ESTO SON EJEMPLOS DE USO DE LA FUNCIÓN calculaMedia
$dato1 = 12;
$dato2 = 16;
// EL TERCER ARGUMENTO INDICA EL TIPO DE MEDIA A CALCULAR
$media = calculaMedia($dato1, $dato2, "geométrica");
print "<p>La media geométrica de $dato1 y $dato2 es $media.</p>\n";
print "\n";
// AL NO PONER EL TERCER ARGUMENTO, DEVUELVE LA MEDIA ARITMÉTICA
$media = calculaMedia($dato1, $dato2);
print "<p>La media aritmética de $dato1 y $dato2 es $media.</p>\n";
?>
<p>La media geométrica de 12 y 16 es 6.9282032302755.</p>
<p>La media aritmética de 12 y 16 es 14.</p>
Tradicionalmente, una limitación de los argumentos predeterminados era que debían ser los últimos en la lista de argumentos, para evitar ambigüedades. Si los valores de los argumentos que se escriben al llamar a la función se van asociando por orden a los argumentos que aparecen en la definición de la función, cuando enviamos menos valores que argumentos, los argumentos a los que PHP no asigna valor son los últimos.
Esta limitación se resolvió en PHP 8.0 (publicado en noviembre de 2020), que introdujo la posibilidad de indicar el nombre de los argumentos al llamar a las funciones, como se comenta en el apartado siguiente.
Desde PHP 8.0 (publicado en noviembre de 2020), PHP permite escribir el nombre de los argumentos junto con el valor del argumento.
<?php
function saludo($saludo, $nombre)
{
print "<p>¡$saludo, $nombre!</p>\n";
print "\n";
}
saludo(saludo: "Hola", nombre: "Don Pepito");
saludo(saludo: "Adios", nombre: "Don José");
?>
<p>¡Hola, Don Pepito!</p>
<p>¡Adios, Don José!</p>
<?php
function saludo($saludo, $nombre)
{
print "<p>¡$saludo, $nombre!</p>\n";
print "\n";
}
saludo(saludo: "Hola", nombre: "Don Pepito");
saludo(nombre: "Don José", saludo: "Adios");
?>
<p>¡Hola, Don Pepito!</p>
<p>¡Adios, Don José!</p>
<?php
function saludo($saludo = "Hola", $nombre = "desconocido")
{
print "<p>¡$saludo, $nombre!</p>\n";
print "\n";
}
saludo();
saludo(saludo: "Adios");
saludo(nombre: "Don Pepito");
saludo(saludo: "Adios", nombre: "Don José");
?>
<p>¡Hola, desconocido!</p>
<p>¡Adios, desconocido!</p>
<p>¡Hola, Don Pepito!</p>
<p>¡Adios, Don José!</p>
Para indicar que una función puede tener un número indeterminado de argumentos, se debe utilizar la expresión ... (tres puntos seguidos).
function nombreDelaFuncion(...$argumentos)
{
bloque_de_sentencias
}
Los argumentos que se escriban al llamar a la función se reciben en una única matriz cuyos valores son los valores de los argumentos enviados, como muestra el siguiente ejemplo.
<?php
function une(...$argumentos)
{
$tmp = "";
// Recorremos la matriz formada por todos los argumentos recibidos
foreach($argumentos as $argumento) {
// Vamos concatenando cada uno de los argumentos recibidos
$tmp = $tmp . $argumento;
}
// Devolvemos la cadena resultante
return $tmp;
}
// Podemos llamar a la función une() con tantos argumentos como queramos
print une("<p>", "abc", "def", "ghi", "</p>", "\n");
print une("\n");
print une("<p>", 1, 2, 3, "</p>", "\n");
?>
<p>abcdefghi</p>
<p>123</p>