问题描述
我想使用 DataProvider
的 subresource
来更改数据库中的某些数据。
但是当我这样做时,它进入了无限循环,我不明白为什么?
<?PHP
namespace App\DataProvider;
use ApiPlatform\Core\DataProvider\SubresourceDataProviderInterface;
class MessageDataProvider implements SubresourceDataProviderInterface
{
private $subresourceDataProvider;
public function __construct(SubresourceDataProviderInterface $subresourceDataProvider)
{
$this->subresourceDataProvider = $subresourceDataProvider;
}
public function getSubresource(string $resourceClass,array $identifiers,array $context,string $operationName = null)
{
return $this->subresourceDataProvider->getSubresource($resourceClass,$identifiers,$context,$operationName);
}
}
解决方法
类 MessageDataProvider
实现了 SubresourceDataProviderInterface
,它也是构造函数中的一个参数 - symfony 可能试图通过将 SubresourceDataProviderInterface
放在构造函数中来自动装配 MessageDataProvider
。但是为了将 MessageDataProvider
放入构造函数中,它必须首先构建此类型的实例。为了做到这一点,需要调用 MessageDataProvider
构造函数......这就是创建无限循环的方式。
如果您打算注入 SubresourceDataProvider
的实体,您可以显式配置 MessageDataProvider
服务。链接到 docs
我在此链接上找到了解决方案
https://github.com/api-platform/core/issues/2816#issuecomment-494579509
<?php
namespace App\DataProvider;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use ApiPlatform\Core\DataProvider\SubresourceDataProviderInterface;
use App\Entity\Note;
class NoteSubresourceDataProvider implements RestrictedDataProviderInterface,SubresourceDataProviderInterface
{
private $alreadyInvoked = false;
private $subresourceDataProvider;
public function __construct(SubresourceDataProviderInterface $subresourceDataProvider)
{
$this->subresourceDataProvider = $subresourceDataProvider;
}
public function getSubresource(string $resourceClass,array $identifiers,array $context,string $operationName = null)
{
$this->alreadyInvoked = true;
$collection = $this->subresourceDataProvider->getSubresource($resourceClass,$identifiers,$context);
return $collection;
}
public function supports(string $resourceClass,string $operationName = null,array $context = []): bool
{
return !$this->alreadyInvoked && Note::class === $resourceClass;
}
}