Symfony 多对多重复条目
Symfony ManyToMany duplicate entry
当我想插入具有 ManyToMany 关系的数据时遇到问题。
当我想使用我的 CategoryType 创建一个新类别时,我只需要名称字段。
在我的 AdminCategoryController 中,我想通过获取我工作的域服务器来强制一个站点。
更新
事实上,我有很多站点和很多域。所有站点都必须使用他的服务器名连接到一个唯一的数据库。
所以我的 VHOST 是为此配置的。
所以,我有 2 个实体:网站、类别
站点实体 :
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\SiteRepository")
*/
class Site
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @ORM\Column(type="string", length=255)
*/
private $domain;
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Category", mappedBy="site")
*/
private $categories;
public function __construct()
{
$this->categories = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getDomain(): ?string
{
return $this->domain;
}
public function setDomain(string $domain): self
{
$this->domain = $domain;
return $this;
}
/**
* @return Collection|Category[]
*/
public function getCategories(): Collection
{
return $this->categories;
}
public function addCategory(Category $category): self
{
if (!$this->categories->contains($category)) {
$category->addSite($this);
$this->categories[] = $category;
}
return $this;
}
public function removeCategory(Category $category): self
{
if ($this->categories->contains($category)) {
$this->categories->removeElement($category);
$category->removeSite($this);
}
return $this;
}
}
类别实体:
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\CategoryRepository")
*/
class Category
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Site", inversedBy="categories", cascade={"persist"})
*/
private $site;
public function __toString(){
return $this->name;
}
public function __construct(Site $site)
{
$this->site = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
/**
* @return Collection|Site[]
*/
public function getSite(): Collection
{
return $this->site;
}
public function addSite(Site $site): self
{
if (!$this->site->contains($site)) {
$this->site[] = $site;
}
return $this;
}
public function removeSite(Site $site): self
{
if ($this->site->contains($site)) {
$this->site->removeElement($site);
}
return $this;
}
}
我通过会话在 SiteService 中获取站点信息:
use App\Repository\SiteRepository;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
class SiteService{
public $infos;
private $session;
private $requestStack;
private $siteRepository;
public function __construct(SessionInterface $session, RequestStack $requestStack, SiteRepository $siteRepository){
$this->session = $session;
$this->requestStack = $requestStack;
$this->siteRepository = $siteRepository;
$this->getInfos();
}
public function getInfos(){
$this->infos = $this->session->get('site');
if(empty($this->infos)){
$request = $this->requestStack->getCurrentRequest();
$server_name = $request->server->get('SERVER_NAME');
$this->infos = $this->siteRepository->findOneBy(['domain'=>$server_name]);
if($this->infos == NULL){
$this->infos = $this->siteRepository->findOneBy([]);
}
$this->session->set('site', $this->infos);
$this->infos = $this->session->get('site');
}
return $this->infos;
}
}
这是我的 CategoryController,用于在站点中添加新类别
/**
* @Route("/new", name="admin.category.new")
* @param Request $request
* @return Response
*/
public function new(Request $request):Response{
$category = new Category();
$form = $this->createForm(CategoryType::class, $category);
$form->handleRequest($request);
$server_name = $request->server->get('SERVER_NAME');
$site = $this->siteRepository->findBy(['domain'=>$server_name]);
$siteFromSession = $this->session->get('site');
if($form->isSubmitted() && $form->isValid()){
$category->addSite($site);
$this->em->persist($category);
$this->em->flush();
return $this->redirectToRoute('admin.category.edit', ['id'=>$category->getId()]);
}
$form = $form->createView();
$params = compact('category', 'form');
return $this->render('admin/category/new.html.twig', $params);
}
两个变量转储不相等..
dump($site);
Site {#187 ▼
-id: 1
-name: "My Website"
转储($siteFromSession);
Site {#623 ▼
-id: 1
-name: "My Website"
如果我使用 $category->addSite($site); 坚持类别
上班了。
但是当我使用 $category->addSite($siteFromSession); 坚持类别时
我在我的数据库中看到当前站点在站点 table 中是重复的并且 category.site 是新站点,而不是我插入的站点。
但是,我不想在每次添加类别时都执行查询。
我只想在第一次登录管理页面时使用会话来获取站点的信息
感谢帮助我
太棒了!!我解决了!
当我想在会话中保存站点信息时,我将其分离,当我想从会话中获取实体时,我将其合并
public function setInfos(){
$request = $this->requestStack->getCurrentRequest();
$server_name = $request->server->get('HTTP_HOST');
$site = $this->siteRepository->findOneBy(['domain'=>$server_name]);
$this->em->detach($site);
$this->session->set('site', $site);
}
public function getInfos()
$site = $this->session->get('site');
$site = $this->em->merge($site);
}
当我想插入具有 ManyToMany 关系的数据时遇到问题。
当我想使用我的 CategoryType 创建一个新类别时,我只需要名称字段。 在我的 AdminCategoryController 中,我想通过获取我工作的域服务器来强制一个站点。
更新 事实上,我有很多站点和很多域。所有站点都必须使用他的服务器名连接到一个唯一的数据库。 所以我的 VHOST 是为此配置的。
所以,我有 2 个实体:网站、类别
站点实体 :
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\SiteRepository")
*/
class Site
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @ORM\Column(type="string", length=255)
*/
private $domain;
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Category", mappedBy="site")
*/
private $categories;
public function __construct()
{
$this->categories = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getDomain(): ?string
{
return $this->domain;
}
public function setDomain(string $domain): self
{
$this->domain = $domain;
return $this;
}
/**
* @return Collection|Category[]
*/
public function getCategories(): Collection
{
return $this->categories;
}
public function addCategory(Category $category): self
{
if (!$this->categories->contains($category)) {
$category->addSite($this);
$this->categories[] = $category;
}
return $this;
}
public function removeCategory(Category $category): self
{
if ($this->categories->contains($category)) {
$this->categories->removeElement($category);
$category->removeSite($this);
}
return $this;
}
}
类别实体:
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\CategoryRepository")
*/
class Category
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Site", inversedBy="categories", cascade={"persist"})
*/
private $site;
public function __toString(){
return $this->name;
}
public function __construct(Site $site)
{
$this->site = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
/**
* @return Collection|Site[]
*/
public function getSite(): Collection
{
return $this->site;
}
public function addSite(Site $site): self
{
if (!$this->site->contains($site)) {
$this->site[] = $site;
}
return $this;
}
public function removeSite(Site $site): self
{
if ($this->site->contains($site)) {
$this->site->removeElement($site);
}
return $this;
}
}
我通过会话在 SiteService 中获取站点信息:
use App\Repository\SiteRepository;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
class SiteService{
public $infos;
private $session;
private $requestStack;
private $siteRepository;
public function __construct(SessionInterface $session, RequestStack $requestStack, SiteRepository $siteRepository){
$this->session = $session;
$this->requestStack = $requestStack;
$this->siteRepository = $siteRepository;
$this->getInfos();
}
public function getInfos(){
$this->infos = $this->session->get('site');
if(empty($this->infos)){
$request = $this->requestStack->getCurrentRequest();
$server_name = $request->server->get('SERVER_NAME');
$this->infos = $this->siteRepository->findOneBy(['domain'=>$server_name]);
if($this->infos == NULL){
$this->infos = $this->siteRepository->findOneBy([]);
}
$this->session->set('site', $this->infos);
$this->infos = $this->session->get('site');
}
return $this->infos;
}
}
这是我的 CategoryController,用于在站点中添加新类别
/**
* @Route("/new", name="admin.category.new")
* @param Request $request
* @return Response
*/
public function new(Request $request):Response{
$category = new Category();
$form = $this->createForm(CategoryType::class, $category);
$form->handleRequest($request);
$server_name = $request->server->get('SERVER_NAME');
$site = $this->siteRepository->findBy(['domain'=>$server_name]);
$siteFromSession = $this->session->get('site');
if($form->isSubmitted() && $form->isValid()){
$category->addSite($site);
$this->em->persist($category);
$this->em->flush();
return $this->redirectToRoute('admin.category.edit', ['id'=>$category->getId()]);
}
$form = $form->createView();
$params = compact('category', 'form');
return $this->render('admin/category/new.html.twig', $params);
}
两个变量转储不相等..
dump($site);
Site {#187 ▼
-id: 1
-name: "My Website"
转储($siteFromSession);
Site {#623 ▼
-id: 1
-name: "My Website"
如果我使用 $category->addSite($site); 坚持类别 上班了。
但是当我使用 $category->addSite($siteFromSession); 坚持类别时 我在我的数据库中看到当前站点在站点 table 中是重复的并且 category.site 是新站点,而不是我插入的站点。
但是,我不想在每次添加类别时都执行查询。 我只想在第一次登录管理页面时使用会话来获取站点的信息
感谢帮助我
太棒了!!我解决了! 当我想在会话中保存站点信息时,我将其分离,当我想从会话中获取实体时,我将其合并
public function setInfos(){
$request = $this->requestStack->getCurrentRequest();
$server_name = $request->server->get('HTTP_HOST');
$site = $this->siteRepository->findOneBy(['domain'=>$server_name]);
$this->em->detach($site);
$this->session->set('site', $site);
}
public function getInfos()
$site = $this->session->get('site');
$site = $this->em->merge($site);
}