如何在 __contstruct 中注入服务?
How inject service in __contstruct?
我想在 __construct
中注入 Symfony\Component\Security\Core\Security
以获取当前用户。它需要我使用 @UniqueEnitity
validator:
<?php
declare(strict_types=1);
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\Security;
//...
/**
* @ApiResource()
* @ORM\Entity(repositoryClass="App\Repository\SimpleEntityRepository")
* @UniqueEntity(fields={"foo", "user"})
*/
class SimpleEntity
{
//...
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User")
* @ORM\JoinColumn(nullable=false)
*/
private $user;
public function __construct(Security $security)
{
$this->user = $security->getUser();
}
//...
}
但我得到错误:Cannot create an instance of App\Entity\SimpleEntity from serialized data because its constructor requires parameter "security" to be present.
请帮忙
Symfony 可以将服务注入到其他服务的构造函数中,但不能注入到实体的构造函数中。
通常在实体上设置当前用户是通过装饰api内置的DataPersister来完成的。然而,持久化几乎发生在处理请求的末尾,而验证则发生得更早。因此,验证器将看不到持久者稍后设置的用户。因此,您需要在流程的早期设置用户,然后再进行验证。这可以通过 decorating Denormalizer 来完成。这是一项服务,因此您可以注入安全服务:
// api/src/Serializer/SimpleEntityDenormalizer
namespace App\Serializer;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\Normalizer\ContextAwareDenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\SerializerAwareInterface;
use Symfony\Component\Serializer\SerializerInterface;
use App\Entity\SimpleEntity;
final class SimpleEntityDenormalizer implements ContextAwareDenormalizerInterface, SerializerAwareInterface
{
private $decorated;
private $security;
public function __construct(DenormalizerInterface $decorated, Security $security)
{
$this->decorated = $decorated;
$this->security = $security;
}
public function supportsDenormalization($data, string $type, string $format = null, array $context = [])
{
if ($type !== SimpleEntity::class) return false;
return $this->decorated->supportsDenormalization($data, $type, $format, $context);
}
public function denormalize($data, string $type, string $format = null, array $context = [])
{
$object = $this->decorated->denormalize($data, $type, $format, $context);
if (null === $object->getUser()) {
$object->setUser($this->security->getUser());
}
return $object;
}
public function setSerializer(SerializerInterface $serializer)
{
if($this->decorated instanceof SerializerAwareInterface) {
$this->decorated->setSerializer($serializer);
}
}
}
将以下内容添加到 api/config/services.yaml:
'App\Serializer\SimpleEntityDenormalizer':
arguments:
$decorated: '@api_platform.jsonld.normalizer.item' ]
这并没有取代装饰服务,而是增加了一个新服务。
我想在 __construct
中注入 Symfony\Component\Security\Core\Security
以获取当前用户。它需要我使用 @UniqueEnitity
validator:
<?php
declare(strict_types=1);
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\Security;
//...
/**
* @ApiResource()
* @ORM\Entity(repositoryClass="App\Repository\SimpleEntityRepository")
* @UniqueEntity(fields={"foo", "user"})
*/
class SimpleEntity
{
//...
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User")
* @ORM\JoinColumn(nullable=false)
*/
private $user;
public function __construct(Security $security)
{
$this->user = $security->getUser();
}
//...
}
但我得到错误:Cannot create an instance of App\Entity\SimpleEntity from serialized data because its constructor requires parameter "security" to be present.
请帮忙
Symfony 可以将服务注入到其他服务的构造函数中,但不能注入到实体的构造函数中。
通常在实体上设置当前用户是通过装饰api内置的DataPersister来完成的。然而,持久化几乎发生在处理请求的末尾,而验证则发生得更早。因此,验证器将看不到持久者稍后设置的用户。因此,您需要在流程的早期设置用户,然后再进行验证。这可以通过 decorating Denormalizer 来完成。这是一项服务,因此您可以注入安全服务:
// api/src/Serializer/SimpleEntityDenormalizer
namespace App\Serializer;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\Normalizer\ContextAwareDenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\SerializerAwareInterface;
use Symfony\Component\Serializer\SerializerInterface;
use App\Entity\SimpleEntity;
final class SimpleEntityDenormalizer implements ContextAwareDenormalizerInterface, SerializerAwareInterface
{
private $decorated;
private $security;
public function __construct(DenormalizerInterface $decorated, Security $security)
{
$this->decorated = $decorated;
$this->security = $security;
}
public function supportsDenormalization($data, string $type, string $format = null, array $context = [])
{
if ($type !== SimpleEntity::class) return false;
return $this->decorated->supportsDenormalization($data, $type, $format, $context);
}
public function denormalize($data, string $type, string $format = null, array $context = [])
{
$object = $this->decorated->denormalize($data, $type, $format, $context);
if (null === $object->getUser()) {
$object->setUser($this->security->getUser());
}
return $object;
}
public function setSerializer(SerializerInterface $serializer)
{
if($this->decorated instanceof SerializerAwareInterface) {
$this->decorated->setSerializer($serializer);
}
}
}
将以下内容添加到 api/config/services.yaml:
'App\Serializer\SimpleEntityDenormalizer':
arguments:
$decorated: '@api_platform.jsonld.normalizer.item' ]
这并没有取代装饰服务,而是增加了一个新服务。