Simon Forsberg
Simon Forsberg

Reputation: 13331

PHP array_filter on objects

I'm trying to use array_filter on an array of objects, and using a public method of the foo-class as a callback. I don't know how to do this though.

I was getting this result: Fatal error: Using $this when not in object context which I can guess is because it's calling the bar method in a static manner, but how to pass the objects to the array_filter callback method properly?

function foobar_filter($obj) {
    return $obj->bar();
}

class foo {
    private $value;
    public function __construct($value) {
        $this->value = $value;
    }
    public function bar() {
        // checking if $this is set to avoid "using this when not in object yadayada"-message
        if ($this) return ($this->value > 10);
        else return false;
    }
}

$arr = array(new foo(12), new foo(42), new foo(4));
var_dump($arr);

// Here is the workaround that makes it work, but I'd like to use the objects' method directly. This is the result that I am expecting to get from $arr3 as well
$arr2 = array_filter($arr, "foobar_filter");
var_dump($arr2);

// I would like this to work, somehow...
$arr3 = array_filter($arr, array(foo, "bar"));
var_dump($arr3);

So the result I expect is an array with two objects of the class foo with the values 12 and 42.

For your information, I am using PHP 5.2.6 but I would be happy if it's possible with any PHP-version.

Upvotes: 7

Views: 14350

Answers (5)

Minwork
Minwork

Reputation: 1022

If you are using PHP 7.1+ you can achieve your goal by:

$arr3 = Arr::filterObjects($arr, 'bar');

using this one class library with useful array functions.

Upvotes: 1

user7429815
user7429815

Reputation: 1

Actually you can do it this way

array_filter($arr, [$this, 'bar'])

Upvotes: -1

davidgrcr
davidgrcr

Reputation: 21

I think you can call it statically like this:

class foo {
    private $value;
    public function __construct($value) {
       $this->value = $value;
    }
    public static function bar($a) {        
        if ($a) return ($a->value > 10);
        else return false;
    }
}

$arr = array(new foo(12), new foo(42), new foo(4));

$arr3 = array_filter($arr, array('foo', "bar"));
var_dump($arr3);

Upvotes: 2

gen_Eric
gen_Eric

Reputation: 227270

The problem is the bar method is not static, and needs to be called on each object. Your foobar_filter method is the way to go. There's no other way, because you need to call bar on each object (thus making array_filter call a different function each time), you can't call it statically.

Upvotes: 1

silly
silly

Reputation: 7887

you can use Closure (>= PHP 5.3) in array_filter method like this

$arrX = array_filter($arr, function($element) {
    return $element->bar();
});
var_dump($arrX)

Upvotes: 6

Related Questions