Как преобразовать объект 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 появляется, я приму это.

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));
Другие вопросы по тегам