Le arrow Function

Le arrow function sono state introdotte in PHP 7.4 come sintassi più concisa per le funzioni anonime.

Sia le funzioni anonime che le arrow function sono implementate usando la classe Closure.

Le arrow function hanno la forma base fn (argument_list) => expr.

Le arrow function supportano le stesse funzionalità delle funzioni anonime, eccetto che l'uso delle variabili dallo scope padre è sempre automatico.

Quando una variabile usata nell'espressione è definita nello scope padre essa sarà implicitamente catturata per valore. Nel seguente esempio, le funzioni $fn1 e $fn2 si comportano allo stesso modo.

Example #1 Le arrow function catturano variabili per valore automaticamente

<?php

$y
= 1;

$fn1 = fn($x) => $x + $y;
// equivalent all'utilizzo di $y per valore:
$fn2 = function ($x) use ($y) {
return
$x + $y;
};

var_export($fn1(3));
?>

Il precedente esempio visualizzerà:

4

Questo funziona anche se le arrow function sono nidificate:

Example #2 Le arrow function catturano variabili per valore automaticamente, anche quando nidificate

<?php

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

Analogamente alle funzioni anonime, la sintassi delle arrow function permette firme di funzioni arbitrarie, inclusi parametri e tipi di ritorno, valori di default, variadiche, così come passaggio di parametri e ritorno per riferimento. Tutti i seguenti sono esempi validi di arrow function:

Example #3 Esempi di arrow function

<?php

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

?>

Le arrow function usano il binding della variabili per valore. Questo è grossomodo equivalente ad eseguire uno use($x) per ogni variabile $x usata all'interno della arrow function. Un binding per valore significa che non è possibile modificare qualsiasi valore dallo scope esterno. Le funzioni anonime possono invece essere usate per il binding per riferimento.

Example #4 I valori dello scope esterno non possono essere modificati dalle arrow function

<?php

$x
= 1;
$fn = fn() => $x++; // Non ha effetto
$fn();
var_export($x); // Produce 1

?>

Log delle modifiche

Versione Descrizione
7.4.0 Le arrow function sono diventate disponibili.

Note

Nota: È possibile usare func_num_args(), func_get_arg(), e func_get_args() dall'interno di una arrow function.

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