PHP, добавляем новый метод в уже существующий объект
2 мая, 2012
Допустим у нас есть объект — курсор из субд. Но мы хотим расширить его, для возвращения объектов. Добавить метод next_object(), который будет использовать метод getNext()
Проблема:
Мы не можем заставить модель возвращать объекты другого типа.
Решение 1: сделать итератор на этот курсор(который тоже является итератором). Сделать много магии для методов и свойств и получить новый итератор с нужным нам свойством.
Решение 2: Для PHP 5.4.0, использовать анонимные функции. О нём я и расскажу:
Внутри мапера, в методе findWhere($where) сделаем добавление анонимной функции в курсор, с передачей колбека и самого курсора
/** * @return MongoCursor */ public function findWhere($where) { $collection=$this->collection->find($where); $callback=$this; $collection->next_object=function() use ($collection, $callback) { $data=$collection->getNext(); $obj=$callback->create_object($data); return ($obj); }; return ($collection); } |
Теперь, по идее можно обращаться к $collection->next_object() и получать объект, созданный мапером. Но к сожалению это не работает, т.к. PHP попробует выполнить user_func_array и не найдёт метод. Для этого присваиваем свойство переменной, значение которого является анонимной функцией и выполняем, через $func():
public function findOneWhere($where) { $collection=$this->findWhere($where); $func=$collection->next_object; return ($func()); } |
Кривенько, но работает.