Как преобразовать объект PHP с частными свойствами, которые являются объектами, в массив с помощью Zend Hydrator?

Код

class Composite
{

    private $a;

    private $b;

    /**
     *
     * @return the $a
     */
    public function getA()
    {
        return $this->a;
    }

    /**
     *
     * @return the $b
     */
    public function getB()
    {
        return $this->b;
    }

    /**
     *
     * @param field_type $a            
     */
    public function setA($a)
    {
        $this->a = $a;
    }

    /**
     *
     * @param field_type $b            
     */
    public function setB($b)
    {
        $this->b = $b;
    }
}

$composite = new Composite();
$composite->setA(1);
$composite->setB(new Composite());
$composite->getB()->setA(2);
$composite->getB()->setB(3);

$x = new \Zend\Hydrator\ClassMethods();
print_r($x->extract($composite));

Вывод

Array
(
    [a] => 1
    [b] => Composite Object
        (
            [a:Composite:private] => 2
            [b:Composite:private] => 3
        )

)

Вопрос

Моя цель - создать массив из объекта, где массив может быть рекурсивным. Zend предоставляет гидратор, который извлекает свойства объектов и помещает их в массив. Но он делает это только на первом уровне и не рекурсирует дальше (т.е. он оставил частные члены как указано выше, когда я хотел, чтобы они были превращены в массив).

Есть ли способ создать массив из такого объекта? Примечание. У меня есть разные объекты в качестве частных членов, это не тот же объект, что и в этом упрощенном примере.

Рассматриваемый Hydrator не рекурсивно извлекает свойства частных объектов.

Я приму другие ответы, в которых не используется Hydrator, при условии, что они достаточно элегантны, но если появится ответ, в котором используется \Zend\Hydrator, я приму его.


person Dennis    schedule 14.03.2017    source источник
comment
Есть несколько способов сделать это, вы можете проверить ZendaggregateHydrator (здесь: framework.zend.com/manual/2.3/en/modules/) или шаблон стратегии (framework.zend.com/manual/2.4/en/modules/)   -  person Unex    schedule 15.03.2017


Ответы (1)


Вы можете переопределить Zend\Hydrator\ClassMethods следующим образом:

namespace Application\Model;
use Zend\Hydrator\ClassMethods as ZendClassMethods;
class ClassMethods extends ZendClassMethods
{
  public function extractValue($name, $value, $object = null)
  {
    $value = parent::extractValue($name, $value, $object);
    if (is_object($value)) {
        return $this->extract($value);
    } else {
        return $value;
    }
  }
}

Затем вы используете Application\Model\ClassMethods вместо Zend\Hydrator\ClassMethods следующим образом

use Application\Model\ClassMethods;
use Application\Model\Composite;

    $composite = new Composite();
    $composite->setA(1);
    $composite->setB(new Composite());
    $composite->getB()->setA(2);
    $composite->getB()->setB(3);

    $x = new ClassMethods();
    print_r($x->extract($composite));
person Alain Pomirol    schedule 17.03.2017