提问者:小点点

DTO和PHP7.4内部的关系:如何水合?


我想知道哪些是好的做法:

假设我有两个实体,一个多个。 两者都是ApiResources,都有一个输出DTO。 所以两个都有变压器。

<?php

/**
 * @ORM\Entity
 * @ApiResource(
 *     output="Dto\Foo"
 * )
 */
class Foo
{
    private int $id;

    /**
    * @ORM\ManyToOne(targetEntity="Bar")
    */
    private Bar $bar;

}

问题是,当我将实体Foo转换为DTO Foo时,我想用Bar DTO来水化它,而不是Bar实体。 但因为我用一个实体来水化它,我就有了一个酒吧实体。 在这个过程的后面,Bar实体被一个Bar DTO替换,ApiPlateform正常工作,但是我的问题是:Bar属性类型会随着时间的推移而被修改(而且它不能进行类型提示)。 在我看来很脏,不是吗?

插图:

Transofer

<?php 

use ApiPlatform\Core\DataTransformer\DataTransformerInterface;

class FooEntityToFooDToTransormer implements DataTransformerInterface
{
    public function transform($object, string $to, array $context = [])
    {
        return new FooDto($object);
        // maybe there is a better way to hydrate FooDto, by getting directly a BarDto here ?
    }
}

DTO:

<?php 

namespace Dto;

class Foo
{
    public int $id;

    // problem is I cant typehint here
    public $bar;

    public function __construct(FooEntity $fooEntity)
    {
        $this->id = $fooEntity->getId();
        $this->bar = $fooEntity->getBar(); // <-- return a Bar entity, transformed later by ApiPlatform into a Bar DTO.
    }
}

有没有一种方法或一个好的做法来适当地水合一个实体的DTO,特别是关于关系?


共1个答案

匿名用户

我想这里有两种可能的解决方案,一种是通过多一个参数扩展DTO的构造函数签名并调整转换器,另一种是在DTO的构造函数中进行转换:

<?php 

namespace Dto;

class FooDto
{
    public BarDto $bar;

    // first variant

    public function __construct(FooEntity $fooEntity, BarDto $barDto)
    {
        $this->id = $fooEntity->getId();
        $this->bar = $barDto;
    }

    // second
    public function __construct(FooEntity $fooEntity)
    {
        $this->id = $fooEntity->getId();
        $this->bar = new BarDto($fooEntity->getBar());
    }
}