Фильтр массивов PHP для объектов


Я пытаюсь использовать array_filter для массива объектов и использую открытый метод класса foo в качестве обратного вызова. Хотя я не знаю, как это сделать.

Я получал этот результат: Fatal error: Using $this when not in object context, который, как я могу догадаться, заключается в том, что он вызывает метод bar статическим способом, но как правильно передать объекты в метод обратного вызова array_filter?

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);

Таким образом, результат, который я ожидаю, представляет собой массив с двумя объектами класса foo со значениями 12 и 42.

Для вашего информация, я использую PHP 5.2.6, но я был бы рад, если бы это было возможно с любой PHP-версией.

Author: Simon Forsberg, 2012-06-13

5 answers

Проблема в том, что метод bar не является статическим, и его необходимо вызывать для каждого объекта. Ваш метод foobar_filter - это правильный путь. Другого способа нет, потому что вам нужно вызывать bar для каждого объекта (таким образом, array_filter каждый раз вызывает другую функцию), вы не можете вызывать ее статически.

 1
Author: Rocket Hazmat, 2012-06-13 14:37:34

Вы можете использовать закрытие (>=PHP 5.3) в методе array_filter следующим образом

$arrX = array_filter($arr, function($element) {
    return $element->bar();
});
var_dump($arrX)
 2
Author: silly, 2012-06-13 14:31:49

Я думаю, что вы можете назвать это статически так:

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);
 2
Author: davidgrcr, 2014-02-06 21:53:10

Если вы используете PHP 7.1+, вы можете достичь своей цели с помощью:

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

Используя эту библиотеку классов с полезными функциями массива.

 1
Author: Minwork, 2018-09-05 22:22:30

На самом деле вы можете сделать это таким образом

array_filter($arr, [$this, 'bar'])
 -1
Author: user7429815, 2017-01-17 10:39:59