91

I've got an array, which I want to filter by an external variable. The situation is as follows:

$id = '1';
var_dump($id);
$foo = array_filter($bar, function($obj){
    if (isset($obj->foo)) {
        var_dump($id);
        if ($obj->foo == $id) return true;
    }
    return false;
});

The first var_dump returns the ID (which is dynamically set ofcourse), however, the second var_dump returns NULL.

Can anyone tell me why, and how to solve it?

4
  • what is $bar and what is the value of $bar Commented Sep 23, 2014 at 11:46
  • 1
    @NitishKumar $bar normally is an array Commented Sep 23, 2014 at 11:49
  • 1
    @php-dev We can say it's definitely an array, because it's not throwing a PHP error. It may not always definitely be an array, depending on the code, but it's definitely an array in the use-case where he gets the error described in the OP Commented Sep 23, 2014 at 11:54
  • Sorry, it is indeed an array with ID's. Commented Sep 23, 2014 at 11:55

3 Answers 3

189

The variable $id isn't in the scope of the function. You need to use the use clause to make external variables accessible:

$foo = array_filter($bar, function($obj) use ($id) {
    if (isset($obj->foo)) {
        var_dump($id);
        if ($obj->foo == $id) return true;
    }
    return false;
});

See documentation for Anonymous functions (Example #3 "Inheriting variables from the parent scope").

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

2 Comments

Note: Requires PHP 5.3.x ... see also stackoverflow.com/a/25994339/42223
@dreftymac 5.3 is required just for anonymous function syntax, it's not specific to the use modifier.
12

Variable scope issue!

Simple fix would be :

$id = '1';
var_dump($id);
$foo = array_filter($bar, function($obj){
    global $id;
    if (isset($obj->foo)) {
        var_dump($id);
        if ($obj->foo == $id) return true;
    }
    return false;
}); 

or, since PHP 5.3

$id = '1';
var_dump($id);
$foo = array_filter($bar, function($obj) use ($id) {
    if (isset($obj->foo)) {
        var_dump($id);
        if ($obj->foo == $id) return true;
    }
    return false;
});

Hope it helps

1 Comment

I don't think the first version would work pre-5.3, since anonymous functions were added in 5.3. Earlier, you'd have to use the create_function() function, along with the global declaration.
9

Because your closure function can't see $id. You need the use keyword:

$foo = array_filter($bar, function($obj) use ($id) {

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.