21

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?

3
  • 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. Commented Nov 28, 2019 at 6:56
  • I presume it's not possible. Commented Nov 28, 2019 at 6:58
  • Does this answer your question? Rewriting an anonymous function in php 7.4 Commented Nov 28, 2019 at 7:27

3 Answers 3

28

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.

Sign up to request clarification or add additional context in comments.

Comments

5

You can use an object to do this.

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

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

var_dump($state->index); // 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.

1 Comment

Clever workaround
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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.