How to convert a PHP Object with private properties that are Objects into an array using Zend Hydrator?

384 Views Asked by At

Code

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

Output

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

)

Question

My goal is to produce an array out of an object where array can be recursive. Zend provides a hydrator that extracts object properties and puts them into array. But it does so on the first level only and it does not recurse further (i.e. it left private members as-is above, when I wanted them to be turned into an array).

Is there any way to produce an array out of an object like this? Note: I have different objects as private members, they are not the same object as is in this simplified example.

Hydrator in question does not go on to extract private object properties recursively.

I will accept other answers that do not use Hydrator, provided they are reasonably elegant, but if an answer that uses \Zend\Hydrator emerges, I will accept that one.

1

There are 1 best solutions below

0
On

You can override Zend\Hydrator\ClassMethods as follows :

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

Then you use Application\Model\ClassMethods instead of Zend\Hydrator\ClassMethods as follows

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