我看到了许多如何在实体之间建立OneToMany关联的例子。但是,我还没有看到任何关于如何从关联中输出数据的内容。(例如转换为JSON或只拥有一个干净的数组)
下面是一些示例代码:
declare(strict_types=1);
namespace Banks\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/basic-mapping.html
*
* @ORM\Entity
* @ORM\Table(name="bank")
**/
class Banks implements \JsonSerializable
{
/**
* @ORM\Id
* @ORM\Column(type="integer", name="id", nullable=false)
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* A Bank could have Many Branches
*
* @ORM\OneToMany(targetEntity="Branches\Entity\Branches", mappedBy="bank")
*
*/
protected $branches;
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $name;
/**
*
* @return array|mixed
*/
public function jsonSerialize()
{
return [
'id' => $this->id,
'name' => $this->name,
'branches' => $this->getBranches()
];
}
public function __construct()
{
$this->branches = new ArrayCollection();
}
public function getBranches(): Collection
{
return $this->branches;
}
// ... Other getter/setters removed
}然后我们也有了分支实体:
declare(strict_types=1);
namespace Branches\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/basic-mapping.html
*
* @ORM\Entity
* @ORM\Table(name="branches")
**/
class Branches implements \JsonSerializable
{
/**
* @ORM\Id
* @ORM\Column(type="integer", nullable=false)
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* A Branch has one Bank
*
* @ORM\ManyToOne(targetEntity="Banks\Entity\Banks", inversedBy="branches")
* @ORM\JoinColumn(name="bank_id", referencedColumnName="id")
*/
protected $bank;
/**
* @ORM\Column(type="integer", nullable=false)
*/
protected $bank_id;
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $name;
/**
*
* @return array|mixed
*/
public function jsonSerialize()
{
return [
'id' => $this->id,
'bank_id' => $this->bank_id,
'name' => $this->name,
'bank' => $this->getBank()
];
}
public function getBank()
{
return $this->bank;
}
// ... Other getter/setters removed
}查询两个实体总体上运行良好,调用$result->jsonSerialize(),然后使用return new JsonResponse($result)返回以获得JSON对象。尽管查询分支具有预期的结果,但作为输出的一部分,我将分行与关联银行一起接收到,但对银行的查询没有返回关联分行,而是显示为"branches": {}
我知道这是因为$branches是一个集合,但是如何以一种方式输出它以成为结果JSON对象的一部分?
我尝试过$this->branches->toArray(),但是这会导致一个不能编码为JSON的对象数组,因此,结果是一个错误。
注意:$this->getBranches()的内容(对象)确实按照预期包含分支,$this->branches->count()可以看到这些分支。但是,如何以允许JsonSerializable创建JSON的方式联系它们呢?
根据请求,下面是留给实体使用的中间件代码:
工厂用于创建Handler所需的内容:
class BanksViewHandlerFactory
{
public function __invoke(ContainerInterface $container) : BanksViewHandler
{
$entityManager = $container->get(EntityManager::class);
$entityManager->getConfiguration()->addEntityNamespace('Banks', 'Banks\Entity');
$entityRepository = $entityManager->getRepository('Banks:Banks');
return new BanksViewHandler($entityManager, $entityRepository);
}
}工厂调用Handler:
class BanksViewHandler implements RequestHandlerInterface
{
protected $entityManager;
protected $entityRepository;
public function __construct(
EntityManager $entityManager,
EntityRepository $entityRepository,
) {
$this->entityManager = $entityManager;
$this->entityRepository = $entityRepository;
}
public function handle(ServerRequestInterface $request) : ResponseInterface
{
$return = $this->entityRepository->find($request->getAttribute('id'));
$result['Result']['Banks'] = $return->jsonSerialize();
return new JsonResponse($result);
}
}处理程序返回JSON。
发布于 2018-11-11 21:03:35
需要注意的是,在实现\JsonSerializable接口时,直接调用jsonSerialize()并不会返回JSON,也不会显式调用此方法。
如文件中所述:
实现JsonSerializable的对象在使用json_encode()编码时可以自定义它们的JSON表示。
实现此接口的目的是强制执行jsonSerialize()方法,在将对象传递给json_encode()时内部调用该方法;例如:
$result = $banksRepository->find($id);
$json = json_encode($result);此外,如果还想序列化子分支实体,则需要:
\JsonSerializable (您已经完成了)ArrayCollection对象返回,包含所有子分支对象。为了确保json_encode()正确地将这些代码编码为JSON,需要使用toArray()将ArrayCollection转换为数组。为了说明-(正如您所指出的,您也实现了这一点):
public function jsonSerialize()
{
return [
'id' => $this->id,
'name' => $this->name,
'branches' => $this->getBranches()->toArray(), // <--
];
}这将像预期的那样序列化您的银行和相关分行实体。希望这会有所帮助:)
https://stackoverflow.com/questions/53252889
复制相似问题