Access Variables from Parent Scope in Anonymous PHP Function

Access variables from parent scope in anonymous PHP function

Use the use keyword to bind variables into the function's scope.

function() use ($db) {

Closures may also inherit variables from the parent scope. Any such variables must be declared in the function header [using use].

http://www.php.net/manual/en/functions.anonymous.php

Why it's not possible to access variables from parent/outer scope in anonymous functions on PHP?

You can capture the variable you need with use.

$world = 'world';

$func = function() use ($world) {
echo 'hello ' . $world;
};

$func();
// hello world

Anonymous function inheriting variable from parent scope which contains variable

Although I'm not a fan of variable variables and prefer arrays, you can solve this before passing the colour to the function...

$color = ${strtoupper($colors[$i])};

PHP scope child anonymous function alter variable in parent function

2021 update courtesy of George

It's no longer necessary. For searchers in the future: If you use the new (PHP>=7.4) "arrow function" notation for anonymous functions, variables in the parent are automatically accessible to you by-value. No use tag needed. php.net/manual/en/functions.arrow.php


After some more digging... why do I always find the answers AFTER I post a question...

Using the use clause on the function you can use the variables you declare there in the "child" scope.
That this isnt highlighted in the scope documentation in php docs beats me.

Extracted from Reference: What is variable scope, which variables are accessible from where and what are "undefined variable" errors?

Extending the scope of variables into anonymous functions

$foo = 'bar';

$baz = function () use ($foo) {
echo $foo;
};

$baz();

After some fiddling I found i can't directly modify array variables. Any modifications stay in the function scope but dont lift over to the parent scope.

I made a simple holder object with setters and getters to get it to work.

function scop1() {
/** simple class to hold vars **/
class holder {
public $held = [];
/** setter **/
function update($what, $with) {
$this->held[$what] = $with;
}
/** getter **/
function get($what) {
if(isset($this->held[$what])) return $this->held[$what];
else return null;
}
}
$var = new holder();
/** works **/
$var->update('hello','bye');
$x = function() use ($var) {
/** modify parent scope **/
$var->update('hello','hello');
};
/** call anomynous function **/
$x();
/** it should say hello hello in held **/
var_dump($var);
}
scop1();

live sample: http://sandbox.onlinephpfunctions.com/code/d7464356c0712f2606b0f70ab952be4d782374dc

PHP: Is there a difference in passing a variable to anonymous function, and using closure function?

The closure function is useful when you don't have control over the arguments that are being passed. For instance, when you use array_map you can't add an additional parameter, it just receives the array elements. You can use the closure to access additional variables.

$string = "foo";
$array = ["abc", "def"];
$new_array = array_map(function($x) use ($string) {
return $string . $x;
}, $array);

Accessing outside variable using anonymous function as params

You have to use use as described in docs:

Closures may also inherit variables from the parent scope. Any such
variables must be declared in the function header. Inheriting
variables from the parent scope is not the same as using global
variables. Global variables exist in the global scope, which is the
same no matter what function is executing.

Code:

$result = '';
fetch("SELECT title FROM tbl", function($r) use (&$result) {
$result .= $r['title'];
});

But beware (taken from one of comments in previous link):

use() parameters are early binding - they use the variable's value at
the point where the lambda function is declared, rather than the point
where the lambda function is called (late binding).

Accessing outer variable in PHP 7 anonymous class

another solution could be

$outer = 'something';

$instance = new class($outer) {

private $outer;

public function __construct($outer) {
$this->outer = $outer
}

public function testing() {
var_dump($this->outer);
}
};

Use variables inside an anonymous function, which is defined somewhere else

The point of the use keyword is to inherit/close over a particular environment state from the parent scope into the Closure when it's defined, e.g.

$foo = 1;

$fn = function() use ($foo) {
return $foo;
};

$foo = 2;

echo $fn(); // gives 1

If you want $foo to be closed over at a later point, either define the closure later or, if you want $foo to be always the current value (2), pass $foo as a regular parameter.



Related Topics



Leave a reply



Submit