13

PHP 7.4 introduced Arrow functions. And it also introduced implicit by-value scope binding which eliminate the need for use keyword.

Now if we want to use a variable out of a closure's scope by reference with a regular anonymous function we would do this:

$num = 10;
call_user_func(function() use (&$num) {
$num += 5;
});
echo $num; // Output: 15

But using an arrow function it seems impossible

$num = 10;
call_user_func(fn() => $num += 5);

echo $num; // Output: 10

So how to use $num variable by reference?

Dharman
  • 30,962
  • 25
  • 85
  • 135
Rain
  • 3,416
  • 3
  • 24
  • 40
  • I think you'll have to pass it as an argument, otherwise its not visible in the functions scope. Though I'm not sure how that'll work in practice, so it might not be possible. – Qirel Nov 28 '19 at 06:56
  • I presume it's not possible. – u_mulder Nov 28 '19 at 06:58
  • Does this answer your question? [Rewriting an anonymous function in php 7.4](https://stackoverflow.com/questions/58882959/rewriting-an-anonymous-function-in-php-7-4) – Dharman Nov 28 '19 at 07:27

3 Answers3

18

Reading the documentation about it, it says...

By-value variable binding
As already mentioned, arrow functions use by-value variable binding. This is roughly equivalent to performing a use($x) for every variable $x used inside the arrow function. A by-value binding means that it is not possible to modify any values from the outer scope:

$x = 1; 
$fn = fn() => $x++; // Has no effect 
$fn(); 
var_dump($x); // int(1)

So it is not possible ATM.

Community
  • 1
  • 1
Nigel Ren
  • 56,122
  • 11
  • 43
  • 55
3

You can use an object to do this.

$state = new stdClass; 
$state->index = 1;

$fn = fn() => $state->index++; // Now, has effect.
$fn();

var_dump($x); // int(2)

It works because objects always pass by reference. I don't encourage you to use this but in some places it's useful.

Mahdi Aslami Khavari
  • 1,755
  • 15
  • 23
0

It's not possible with the argument-less arrow function, but you can always define an argument inside as a reference. There is no other way using it with arrow functions.

$num = 10;
$fn = fn(&$num) => $num += 5;
$fn($num);

echo $num; // Output: 15
Jsowa
  • 9,104
  • 5
  • 56
  • 60