Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot call variable outside array_filter() [duplicate]

Why i cannot call variable outside array_filter(), this my code

class JsonSelect
{
    public function jsonSource($jsonSource, $val){

        $file_contents = file_get_contents($jsonSource);

        if(!$file_contents){
            throw new Exception('Invalid file name');
        }

        $json = json_decode($file_contents, true);
        $q = $_POST['q'];
        $filtered = $json;

        if(strlen($q)) {
            $filtered = array_filter($json, function ($key) use ($q) {
                if (stripos($key[$val], $q) !== false) {
                    return true;
                } else {
                    return false;
                }
            });
        }

        echo json_encode(array_slice(array_values($filtered), 0, 20));
    }
}

and this my picture to describe my problem. parameter $valcannot be called inside $key[$val] enter image description here

like image 906
Khoerodin Avatar asked Feb 08 '23 23:02

Khoerodin


2 Answers

The scope of the variables inside an anonymous function is ONLY within the anonymous function.

You need to inherit the variable from the parent scope. You can find more details about it in the PHP Documentation about anonymous functions (Example #3)

which would transform this line:

$filtered = array_filter($json, function ($key) use ($q) {

into this:

$filtered = array_filter($json, function ($key) use ($q, $val) {
like image 181
Dragos Avatar answered Feb 11 '23 17:02

Dragos


Add another variable in use:

$filtered = array_filter($json, function ($key) use ($q, $key) {
                if (stripos($key[$val], $q) !== false) {
                    return true;
                } else {
                    return false;
                }
            });

EDIT:

One of good explanations can be found here: https://teamtreehouse.com/community/variable-functions-vs-php-closures

...the benefit of a lambda is that it exists only as long as the variable it is assigned to has a reference. So the way PHP manages memory is by reference counting. Essentially, the PHP engine reads all the files it needs in order to execute the program, and while doing so it finds all the variables used and keeps a tally of how many times they are used( reference count). While the script is being executed each time the variable is used it subtracts one from the reference count. Once the reference count hits zero, the variable is deleted (more or less). Normally, a function is loaded into memory and stays there for the entire execution of the script. However, a lambda can be deleted from memory once the reference count of its variable hits zero.

A closure on the other hand is an anonymous function that encapsulates a part of the global scope at the time it is created. In other words, you can pass a variable to a closure using the "use" keyword and that variable's value will be the same as it was when the closure was created regardless of what happen's outside the closure...

Basically use keyword is needed in order to created isolated scope for variables. Without it You wouldn't be able to inject any additional variable to the function.

like image 44
Adam Avatar answered Feb 11 '23 19:02

Adam