0

I'm passing a variable into anonymous function (closure) via use, and within the closure body I'm modifying the variables value:

$myVar = false;
$myAnonFunc = function() use ($myVar) {
    $myVar = true;
};
$myAnonFunc();
echo '$myVar => ' . ($myVar ? 'TRUE' : 'FALSE') . PHP_EOL;
// Expected `$myVar => TRUE` but got `$myVar => FALSE`

I'm expecting $myVar within the closure to be bound to the $myVar in the parent scope, such that changes to the $myVar variable within the closure are reflected in the parent. This doesn't appear to be happening. How is understanding of PHP closures incorrect and what should my expectation be? How can actually do what I want?

REPL of the above code

Dan Stevens
  • 6,392
  • 10
  • 49
  • 68

3 Answers3

3

The $myVar in the closure scope is a copy. Changing it won't change the variable in the parent scope.

What you can do if to pass a reference of the variable instead.

$myAnonFunc = function() use (&$myVar) {
    $myVar = true;
};

This will behave as you expect.

Federkun
  • 36,084
  • 8
  • 78
  • 90
3

Because changes in block scope stays in block scope. If you want changes at its address data, then you can pass by reference.

$myVar = false;
$myAnonFunc = function() use (&$myVar) { // changes will be reflected at its address
    $myVar = true;
};
$myAnonFunc();
echo '$myVar => ' . ($myVar ? 'TRUE' : 'FALSE') . PHP_EOL;
// Expected `$myVar => TRUE` but got `$myVar => FALSE`

Demo

Output

$myVar => TRUE
Rahul
  • 18,271
  • 7
  • 41
  • 60
3

You need to pass reference to $myVar

$myAnonFunc = function() use (&$myVar) {
    $myVar = true;
};
Vo Kim Nguyen
  • 1,613
  • 10
  • 14