zf2 - 嵌套聚合水合物

时间:2017-07-19 21:16:39

标签: zend-framework2 zend-hydrator

是否可以嵌套聚合水合物?如果我有以下课程:

class Appointment{
    public date;
    public startTime;
    public endTime;
    public User; //* @var User */
}

class User{
    public Location; //* @var Location*/ 
}

...使用以下AggregateHydrator(从工厂创建)填充:

class AppointmentModelHydratorFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator) {
        $serviceManager = $serviceLocator->getServiceLocator();
        $arrayHydrator = new ArraySerializable();
        $arrayHydrator->addStrategy('date', new DateTimeStrategy())
            ->addStrategy('endTime', new TimeStrategy())
            ->addStrategy('startTime', new TimeStrategy());

        $aggregateHydrator = new AggregateHydrator();
        $aggregateHydrator->add($arrayHydrator);
        $aggregateHydrator->add($serviceLocator->get('Hydrator\User'));
        return $aggregateHydrator;
    }
}

UserHydratorFactory看起来像:

class UserHydratorFactory implements FactoryInterface
{
     public function createService(ServiceLocatorInterface $serviceLocator) {
        $sm = $serviceLocator->getServiceLocator();
        $userHydrator = new UserHydrator($sm->get('User\Mapper'));
        $aggregateHydrator = new AggregateHydrator();
        $aggregateHydrator->add($userHydrator );
        $aggregateHydrator->add($sm->get('HydratorManager')->get('Hydrator\User\Location'));
        return $aggregateHydrator;
}

}

当模型被返回为null时,这是一个预测,但如果我注释掉将位置水合器添加到User水合器,它可以正常工作(尽管没有加载位置数据)。所以我想知道聚合水合物是否能够嵌套?

1 个答案:

答案 0 :(得分:0)

它不是内置的,但可行。

namespace Hydrator;
use Zend\Stdlib\Hydrator\HydratorInterface;
class NestedHydrator implements HydratorInterface
{
    protected $inner_hydrator;
    private $empty;


    public function __construct ($inner_hydrator, $empty)
    {
        $this->inner_hydrator = $inner_hydrator;
        $this->empty = $empty;
    }


    public function extract ($object)
    {
        return [
            $this->getPath() => $this->inner_hydrator->extract ($object->{$this->getPath()})
        ];
    }


    public function hydrate (array $data, $object)
    {
        $object->{$this->getPath()} = $this->inner_hydrator->hydrate ($data [$this->getPath()], $this->empty);

        return $object;
    }


    protected function getPath ()
    {
        return get_class ($this->empty);
    }
}

然后:

$u = new User();
$u->Location = "4 Clinton Rd.";

$a = new Appointment();
$a->date = "yesterday";
$a->startTime = "7:00";
$a->endTime = "8:00";
$a->User = $u;

$h = new AggregateHydrator();
$h->add (new ObjectProperty());
$nested = new \Hydrator\NestedHydrator(new ObjectProperty(), new User());
$h->add ($nested);
$data = $h->extract ($a);

$b = $h->hydrate ($data, new Appointment());
$this->assertEquals ($a, $b);