PHP
Programación Funcional
Buscar..
Introducción
La programación funcional de PHP se basa en funciones. Las funciones en PHP proporcionan un código organizado y reutilizable para realizar un conjunto de acciones. Las funciones simplifican el proceso de codificación, evitan la lógica redundante y hacen que el código sea más fácil de seguir. Este tema describe la declaración y la utilización de funciones, argumentos, parámetros, declaraciones de devolución y alcance en PHP.
Asignación a variables
Las funciones anónimas se pueden asignar a variables para su uso como parámetros donde se espera una devolución de llamada:
$uppercase = function($data) {
return strtoupper($data);
};
$mixedCase = ["Hello", "World"];
$uppercased = array_map($uppercase, $mixedCase);
print_r($uppercased);
Estas variables también se pueden utilizar como llamadas a funciones independientes:
echo $uppercase("Hello world!"); // HELLO WORLD!
Usando variables externas
La construcción de use
se utiliza para importar variables en el alcance de la función anónima:
$divisor = 2332;
$myfunction = function($number) use ($divisor) {
return $number / $divisor;
};
echo $myfunction(81620); //Outputs 35
Las variables también se pueden importar por referencia:
$collection = [];
$additem = function($item) use (&$collection) {
$collection[] = $item;
};
$additem(1);
$additem(2);
//$collection is now [1,2]
Pasando una función de devolución de llamada como parámetro
Hay varias funciones de PHP que aceptan funciones de devolución de llamada definidas por el usuario como un parámetro, como: call_user_func()
, usort()
y array_map()
.
Dependiendo de dónde se definió la función de devolución de llamada definida por el usuario, hay diferentes maneras de pasarlas:
Estilo procesal:
function square($number)
{
return $number * $number;
}
$initial_array = [1, 2, 3, 4, 5];
$final_array = array_map('square', $initial_array);
var_dump($final_array); // prints the new array with 1, 4, 9, 16, 25
Estilo orientado a objetos:
class SquareHolder
{
function square($number)
{
return $number * $number;
}
}
$squaredHolder = new SquareHolder();
$initial_array = [1, 2, 3, 4, 5];
$final_array = array_map([$squaredHolder, 'square'], $initial_array);
var_dump($final_array); // prints the new array with 1, 4, 9, 16, 25
Estilo orientado a objetos utilizando un método estático:
class StaticSquareHolder
{
public static function square($number)
{
return $number * $number;
}
}
$initial_array = [1, 2, 3, 4, 5];
$final_array = array_map(['StaticSquareHolder', 'square'], $initial_array);
// or:
$final_array = array_map('StaticSquareHolder::square', $initial_array); // for PHP >= 5.2.3
var_dump($final_array); // prints the new array with 1, 4, 9, 16, 25
Usando funciones incorporadas como devoluciones de llamada
En las funciones que se pueden callable
como un argumento, también puede poner una cadena con la función incorporada de PHP. Es común usar trim
como parámetro array_map
para eliminar los espacios en blanco array_map
y finales de todas las cadenas en la matriz.
$arr = [' one ', 'two ', ' three'];
var_dump(array_map('trim', $arr));
// array(3) {
// [0] =>
// string(3) "one"
// [1] =>
// string(3) "two"
// [2] =>
// string(5) "three"
// }
Función anónima
Una función anónima es solo una función que no tiene nombre.
// Anonymous function
function() {
return "Hello World!";
};
En PHP, una función anónima se trata como una expresión y, por este motivo, debe terminar con un punto y coma ;
.
Una función anónima debe ser asignada a una variable.
// Anonymous function assigned to a variable
$sayHello = function($name) {
return "Hello $name!";
};
print $sayHello('John'); // Hello John
O debería pasarse como parámetro de otra función.
$users = [
['name' => 'Alice', 'age' => 20],
['name' => 'Bobby', 'age' => 22],
['name' => 'Carol', 'age' => 17]
];
// Map function applying anonymous function
$userName = array_map(function($user) {
return $user['name'];
}, $users);
print_r($usersName); // ['Alice', 'Bobby', 'Carol']
O incluso ha sido devuelto de otra función.
Funciones anónimas autoejecutables:
// For PHP 7.x
(function () {
echo "Hello world!";
})();
// For PHP 5.x
call_user_func(function () {
echo "Hello world!";
});
Pasando un argumento a funciones anónimas autoejecutables:
// For PHP 7.x
(function ($name) {
echo "Hello $name!";
})('John');
// For PHP 5.x
call_user_func(function ($name) {
echo "Hello $name!";
}, 'John');
Alcance
En PHP, una función anónima tiene su propio alcance como cualquier otra función de PHP.
En JavaScript, una función anónima puede acceder a una variable fuera del alcance. Pero en PHP, esto no está permitido.
$name = 'John';
// Anonymous function trying access outside scope
$sayHello = function() {
return "Hello $name!";
}
print $sayHello('John'); // Hello !
// With notices active, there is also an Undefined variable $name notice
Cierres
Un cierre es una función anónima que no puede acceder fuera del alcance.
Al definir una función anónima como tal, está creando un "espacio de nombres" para esa función. Actualmente solo tiene acceso a ese espacio de nombres.
$externalVariable = "Hello";
$secondExternalVariable = "Foo";
$myFunction = function() {
var_dump($externalVariable, $secondExternalVariable); // returns two error notice, since the variables aren´t defined
}
No tiene acceso a ninguna variable externa. Para otorgar este permiso para que este espacio de nombres acceda a variables externas, debe introducirlo mediante cierres ( use()
).
$myFunction = function() use($externalVariable, $secondExternalVariable) {
var_dump($externalVariable, $secondExternalVariable); // Hello Foo
}
Esto se atribuye en gran medida al alcance de la variable ajustada de PHP: si una variable no está definida dentro del alcance, o no se incluye en global
entonces no existe.
También tenga en cuenta:
Heredar variables del ámbito principal no es lo mismo que usar variables globales. Las variables globales existen en el ámbito global, que es el mismo sin importar qué función se esté ejecutando.
El ámbito principal de un cierre es la función en la que se declaró el cierre (no necesariamente la función desde la que se llamó).
Tomado de la documentación de PHP para funciones anónimas
En PHP, los cierres utilizan un enfoque de enlace temprano . Esto significa que las variables pasadas al espacio de nombres del cierre utilizando la palabra clave use
tendrán los mismos valores cuando se definió el cierre.
Para cambiar este comportamiento debes pasar la variable por referencia .
$rate = .05;
// Exports variable to closure's scope
$calculateTax = function ($value) use ($rate) {
return $value * $rate;
};
$rate = .1;
print $calculateTax(100); // 5
$rate = .05;
// Exports variable to closure's scope
$calculateTax = function ($value) use (&$rate) { // notice the & before $rate
return $value * $rate;
};
$rate = .1;
print $calculateTax(100); // 10
Los argumentos predeterminados no se requieren implícitamente al definir funciones anónimas con / sin cierres.
$message = 'Im yelling at you';
$yell = function() use($message) {
echo strtoupper($message);
};
$yell(); // returns: IM YELLING AT YOU
Funciones puras
Una función pura es una función que, dada la misma entrada, siempre devolverá la misma salida y no tendrá efectos secundarios .
// This is a pure function
function add($a, $b) {
return $a + $b;
}
Algunos efectos secundarios son cambiar el sistema de archivos , interactuar con las bases de datos , imprimir en la pantalla .
// This is an impure function
function add($a, $b) {
echo "Adding...";
return $a + $b;
}
Objetos como función.
class SomeClass {
public function __invoke($param1, $param2) {
// put your code here
}
}
$instance = new SomeClass();
$instance('First', 'Second'); // call the __invoke() method
Un objeto con un método __invoke
se puede utilizar exactamente como cualquier otra función.
El método __invoke
tendrá acceso a todas las propiedades del objeto y podrá llamar a cualquier método.
Métodos funcionales comunes en PHP
Cartografía
Aplicando una función a todos los elementos de una matriz:
array_map('strtoupper', $array);
Tenga en cuenta que este es el único método de la lista donde la devolución de llamada es lo primero.
Reducción (o plegado)
Reduciendo una matriz a un solo valor:
$sum = array_reduce($numbers, function ($carry, $number) {
return $carry + $number;
});
Filtración
Devuelve solo los elementos de la matriz para los que la devolución de llamada devuelve true
:
$onlyEven = array_filter($numbers, function ($number) {
return ($number % 2) === 0;
});