Fonction Fléchée

Les fonctions fléchées ont été introduites en PHP 7.4 en tant que syntaxe plus concise pour les fonctions anonymes.

Les fonctions anonymes comme les fonctions fléchées sont implémentées en utilisant la classe Closure.

Les fonctions fléchées ont la forme basique fn (argument_list) => expr.

Les fonctions fléchées supportent les mêmes fonctionnalités que les fonctions anonymes, à l'exception que l'utilisation des variables de la portée parente est automatique.

Quand une variable utilisée dans l'expression est définie dans la portée parente, elle sera implicitement capturée par valeur. Dans l'exemple suivant, les fonctions $fn1 et $fn2 se comportent de façon identique.

Exemple #1 Les fonctions fléchées capturent les variables par valeur automatiquement

<?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));
?>

L'exemple ci-dessus va afficher :

4

Ceci fonctionne aussi si les fonctions fléchées sont imbriquées :

Exemple #2 Les fonctions fléchées capturent les variables par valeur automatiquement, même imbriquées

<?php

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

Similairement aux fonctions anonymes, la syntaxe des fonctions fléchées permet les signatures de fonction arbitraire, ceci inclus les types de paramètres et de retour, valeur par défaut, variable, aussi bien que le passage et retour par référence. Tous les exemples suivants sont des fonctions fléchées valides :

Exemple #3 Exemples de fonctions fléchées

<?php

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

?>

Les fonctions fléchées lie les variables par valeur. Ceci est à peu près équivalent à effectuer un use($x) pour chaque variable $x utilisée à l'intérieur de la fonction fléchée. Un liage par valeur signifie qu'il n'est pas possible de modifier une valeur de la portée extérieure. Les fonctions anonymes peuvent être utilisées à la place pour des liaisons par référence.

Exemple #4 Valeurs de la portée extérieure ne peuvent pas être modifiées par les fonctions fléchées

<?php

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

?>

Historique

Version Description
7.4.0 Les fonctions fléchées sont désormais disponibles.

Notes

Note: Il est possible d'utiliser func_num_args(), func_get_arg(), et func_get_args() depuis l'intérieur d'une fonction fléchée.

add a note add a note

User Contributed Notes 5 notes

up
8
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
13
Koushil Mankali
3 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
9
dexen dot devries at gmail dot com
3 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
1
itsunclexo at gmail dot com
2 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
-1
zhangchengming at kkguan dot com
3 years ago
<?php

$x
= 1;

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

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