Funciones de flecha

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

Tanto las funciones anónimas como las funciones de flecha se implementan utilizando la clase Closure.

Las funciones de las flechas tienen la forma básica fn (argument_list) => expr.

Las funciones de las flechas soportan las mismas características que las funciones anónimas, excepto que el uso de variables del ámbito padre siempre es automático.

Cuando una variable utilizada en la expresión se define en el ámbito padre será implícitamente capturada por valor. En el siguiente ejemplo, las funciones $fn1 y $fn2 se comportan de la misma manera.

Ejemplo #1 Las funciones de flecha capturan las variables por valor automáticamente

<?php

$y
= 1;

$fn1 = fn($x) => $x + $y;
// equivalent to using $y by value:
$fn2 = function ($x) use ($y) {
return
$x + $y;
};

var_export($fn1(3));
?>

El resultado del ejemplo sería:

4

Esto también funciona si las funciones de la flecha están anidadas:

Ejemplo #2 Las funciones de flecha capturan variables por valor automáticamente, incluso cuando están anidadas

<?php

$z
= 1;
$fn = fn($x) => fn($y) => $x * $y + $z;
// Outputs 51
var_export($fn(5)(10));
?>

De manera similar a las funciones anónimas, la sintaxis de la función de la flecha permite firmas de funciones arbitrarias, incluyendo los tipos de parámetros y de retorno, valores por defecto, variadades, así como por referencia al pasar y al regresar. Todos los siguientes son ejemplos válidos de las funciones de las flechas:

Ejemplo #3 Ejemplos de funciones de flecha

<?php

fn(array $x) => $x;
static fn():
int => $x;
fn(
$x = 42) => $x;
fn(&
$x) => $x;
fn&(
$x) => $x;
fn(
$x, ...$rest) => $rest;

?>

Las funciones de flecha utilizan la unión variable por valor. Esto es aproximadamente equivalente a realizar un use($x) para cada variable $x usada dentro de la función de la flecha. Una unión por valores significa que no es posible modificar ningún valor desde el ámbito exterior. Funciones anónimas se pueden utilizar en su lugar para las asignaciones por referencia.

Ejemplo #4 Los valores del alcance exterior no pueden ser modificados por las funciones de flecha

<?php

$x
= 1;
$fn = fn() => $x++; // No tiene ningún efecto
$fn();
var_export($x); // Salida 1

?>

Historial de cambios

Versión Descripción
7.4.0 Las funciones de flecha se hicieron disponibles.

Notas

Nota: Es posible utilizar func_num_args(), func_get_arg(), y func_get_args() desde dentro de una función de flecha.

add a note add a note

User Contributed Notes 5 notes

up
34
InvisibleSmiley
3 years ago
Unlike anonymous functions, arrow functions cannot have a void return type declaration.

May seem obvious, but if you thought you could make use of the benefits of arrow functions (using variables from the parent scope) to simplify a function or method call, keep in mind that this is only possible if you do NOT tell PHP that the arrow function does indeed return void.
up
35
Koushil Mankali
4 years ago
In example 4  (Values from the outer scope cannot be modified by arrow functions)

<?php

$x
= 1;
$fn = fn() => $x++; // Has no effect
$fn();
var_export($x);  // Outputs 1

?>

Here we can use reference variable in fn(&$x) and pass the value from function call $fn($x) so that we will get the output as expected with out using Anonymous functions.

Example:

<?php

$x
= 1;
$fn = fn(&$x) => $x++;
$fn($x);
var_export($x);

?>

Output : 2 (as expected)

But here it will not take values from parent scope automatically but we have to pass them explicitly.
up
14
itsunclexo at gmail dot com
3 years ago
As you already know, variable bindings occur in arrow functions by "by-value".  That means, an arrow function returns a copy of the value of the variable used in it from the outer scope.

Now let us see an example of how a arrow function returns a reference instead of a copy of a value.

<?php

$x
= 0;

$fn = fn &(&$x) => $x// Returns a reference

$y = &$fn($x);  // Now $y represents the reference

var_dump($y);  // Outputs: 0

$y = 3// Changing value of $y affects $x

var_dump($x);  // Ouputs: 3

?>
up
11
dexen dot devries at gmail dot com
4 years ago
Beware compact() not being able to access (import) variables from external scope (known in versions: 7.4.0, 7.4.8) (bug: https://bugs.php.net/bug.php?id=78970).

A workaround is available - use the variable directly; this will cause it to be imported into the arrow function's namespace and make it available to the compact() too.

<?php
$aa
= 111;
$accessing_variable_works = fn($bb) => [ $aa, $bb ];
$compact_is_broken = fn($bb) => compact('aa', 'bb');
$compact_can_work_with_workaround = fn($bb) => compact('aa', 'bb') + ['workaround' => $aa];
var_dump($accessing_variable_works(333));
var_dump($compact_is_broken(555));
var_dump($compact_can_work_with_workaround(777));
?>

result:
array(2) {
  [0]=>
  int(111)
  [1]=>
  int(333)
}
PHP Notice:  compact(): Undefined variable: aa in /home/m/vlt/guitar/tlb/s/public_html/index.php on line 9
array(1) {
  ["bb"]=>
  int(555)
}
array(3) {
  ["aa"]=>
  int(111)
  ["bb"]=>
  int(777)
  ["workaround"]=>
  int(111)
}
up
-44
zhangchengming at kkguan dot com
4 years ago
<?php

$x
= 1;

(
fn() => print($x))(); // Outputs 1

(fn($x) => print($x))(2); // Outputs 2
To Top