Arrow Functions

Arrow functions foram introduzidos a partir do PHP 7.4 como uma sintaxe mais concisa para funções anônimas.

Funções anônimas e arrow functions são implementadas usando a classe Closure.

Arrow functions tem a forma básica fn (argument_list) => expr.

Arrow functions possuem a mesmas características das funções anônimas, exceto que o uso de variáveis do escopo pai é sempre automático.

Quando uma variável usada na expressão é definida no escopo pai ele será implicitamente capturado por valor. No exemplo a seguir, as funções $fn1 e $fn2comportam-se da mesma maneira.

Exemplo #1 Arrow functions capturam variáveis por valor automaticamente

<?php

$y
= 1;

$fn1 = fn($x) => $x + $y;
// Equivalente ao usar $y por valor:
$fn2 = function ($x) use ($y) {
return
$x + $y;
};

var_export($fn1(3));
?>

O exemplo acima produzirá:

4

Isso também funciona se as arrow de functions estiverem aninhadas:

Exemplo #2 Arrow functions capturam variáveis por valor automaticamente, mesmo quando aninhadas

<?php

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

Da mesma forma que funções anônimas, a sintaxe das arrow functions permitem assinaturas de função arbitrária, incluindo parâmetros e tipos de retorno, valores padrão, variadics, bem como por referência passando e retornando. Todos os exemplos válidos de arrow functions:

Exemplo #3 Examplos de arrow functions

<?php

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

?>

Arrow functions usam vinculação de variável por valor. Isso é aproximadamente equivalente a realizar um use($x) para cada variável $x usada dentro da arrow function. Uma passagem de variável por valor, significa que não é possível modificar quaisquer valores do escopo externo. Funções anônimas podem ser usadas em vez disso para passagem de variável por referência.

Exemplo #4 Valores do escopo externo não podem ser modificados por arrow functions

<?php

$x
= 1;
$fn = fn() => $x++; // Não tem efeito
$fn();
var_export($x); // Imprime 1

?>

Registro de Alterações

Versão Descrição
7.4.0 Arrow functions tornou-se disponível.

Notas

Nota: É possível usar func_num_args(), func_get_arg(), e func_get_args() de dentro de uma arrow functions.

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