推荐的方法是要求构造函数参数中的关联实体对象,可选地与工厂(例如实体存储库)结合,以Group
在实例化期间提供实体。这可确保实体始终处于有效状态。
src/Entity/Person.php
namespace App\Entity;
/**
* @ORM\Entity(repositoryClass="App\Repository\PersonRepository")
*/
class Person
{
//...
public function __construct($name, Group $group)
{
$this->setName($name);
$this->setGroup($group);
}
//...
}
src/Repsotory/PersonRepository.php
namespace App\Repsotory;
use App\Entity\Group;
use App\Entity\Person;
class PersonRepository
{
const DEFAULT_GROUP = 122;
public function create($name, Group $group = null)
{
if (null === $group) {
$group = $this->_em->getReference(Group::class, self::DEFAULT_GROUP);
}
$person = new Person($name, $group);
$this->_em->persist($person);
return $person;
}
}
这允许您仅依靠 Doctrine ORM 实体管理器来维护默认的组关联。
$person = $em->getRepository(Person::class)->create('Mike');
$group = $person->getGroup();
echo $group->getId(); //outputs: 122
$em->flush();
这种方法可以在 Symfony 中扩展以使用查询服务而不是理论实体存储库,以提供处理实体实例化的中心位置。
在 Symfony 3.4+ 中,您可以使用存储库服务
为存储库提供依赖注入,而不是使用EntityManagerInterface
.
src/Service/PersonCreateQuery.php
namespace App\Service;
use App\Entity\Group;
use App\Entity\Person;
use Doctrine\ORM\EntityManagerInterface;
class PersonCreateQuery
{
private $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
public function __invoke($name)
{
$group = $this->em->getReference(Group::class, 122);
$person = new Person($name, $group);
$this->em->persist($person);
return $person;
}
}
现在您可以使用依赖注入来检索查询服务并根据需要使用它,例如使用 Symfony 表单或控制器。
namespace App\Controller;
use App\Service\PersonCreateQuery;
class PersonController
{
public function createAction(PersonCreateQuery $query)
{
$person = $query('Mike');
$this->getDoctrine()->getManager()->flush();
//...
}
}
注意: 的用法$em->getReference()
可以替换为$em->find()
。using$em->getReference()
将阻止对数据库的查询,但如果引用无效,则会抛出异常,而 using$em->find()
将返回null
。
另一种方法是使用实体中的生命周期回调或事件侦听器来执行更复杂的功能。但是,这将导致您的实体被实例化为无效状态,直到它被持久化。
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
*/
class Person
{
const DEFAULT_GROUP = 122;
/** @ORM\Column(type="string") */
private $name = 'Mike';
/**
* @ORM\ManyToOne(targetEntity="Group", inversedBy="persons")
* @ORM\JoinColumn(referencedColumnName="id")
*/
private $group;
//....
public function setGroup(Group $group)
{
$this->group = $group;
$group->addPerson($this);
}
/**
* @param LifecycleEventArgs $event
* @ORM\PrePersist
*/
public function onPrePersist(LifecycleEventArgs $event)
{
if (!$this->group instanceof Group) {
/** set default group if not specified */
$group = $event->getEntityManager()->getReference(Group::class, self::DEFAULT_GROUP);
$this->setGroup($group);
}
}
}
现在,当您持久化一个 Person 实体时,如果它没有在其他地方显式设置,它将添加该组。
$person = new Person();
$person->setName('Foo Bar');
$em->persist($person); //persist or do nothing if already persisted
$group = $person->getGroup();
echo $group->getId(); //outputs: 122
$groupPerson = $group->getPerson();
echo $groupPerson->getName(); //outputs: Foo Bar
$em->flush(); //save to database
为了理智,这里是教义事件文档的链接: