Symfony 4,查找()一个实体
Symfony 4, find() an entity
多亏了 symfony 文档 https://symfony.com/doc/current/doctrine.html#updating-an-object,我能够使用名为 'Produit'.
的实体中的 get/set 方法
但是当我调用方法 setProduit()(来自 Paniers 实体)时,Phpstorm 为 $produitSelected 说 "expected App\Entity\Paniers, got Object"。
我不知道为什么 phpstorm 说因为我能够使用方法,有什么问题?
find() return 一个实体对象,对吧?
class PaniersController extends AbstractController
{
/**
* @Route("/paniers/add/{id}", name="paniers.add")
*/
public function addPanier(Request $request, Environment $twig, RegistryInterface $doctrine, $id)
{
$produitSelected = $doctrine->getRepository(Produit::class)->find($id);
if (!$produitSelected) {
throw $this->createNotFoundException(
'Pas de produit trouvé pour l\' id : '.$id
);
}
$lignePanier=$doctrine->getRepository(Paniers::class)->findOneBy(['produit' => $produitSelected, 'user' =>$this->getUser()]);
if($produitSelected->getStock()>0){
if ($lignePanier){
$quantite =$lignePanier->getQuantite();
$lignePanier->setQuantite($quantite+1);
} else {
$lignePanier = new Paniers();
$lignePanier->setUser($this->getUser())
->setDateAjoutPanier(new \DateTime(date('Y-m-d')))
->setQuantite(1)
->setProduit($produitSelected);
}
$doctrine->getManager()->persist($lignePanier);
$produitSelected->setStock($produitSelected->getStock()-1);
$doctrine->getManager()->persist($produitSelected);
$doctrine->getManager()->flush();
}
}
}
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\PaniersRepository")
* @ORM\Table(name="paniers")
*/
class Paniers
{
//...
/**
* @ORM\ManyToOne(targetEntity="Produit")
* @ORM\JoinColumn(name="produit_id", referencedColumnName="id")
*/
private $produit;
public function getProduit(): ?Produit
{
return $this->produit;
}
public function setProduit(?Produit $produit): self
{
$this->produit = $produit;
return $this;
}
}
PhpStorm 显然没有那么聪明,无法理解在这种情况下 find($id)
的 return 值的实际类型将是 Produit
。但你可以帮助它:
/** @var Produit $produitSelected */
$produitSelected = $doctrine->getRepository(Produit::class)->find($id);
要使其正常工作,您应该将 Produit
与完整命名空间一起使用,或者直接在类型提示中添加命名空间。
当然这不能保证或确定实际类型将是 Produit
。所以,如果你犯了错误,PhpStorm 会报告错误的类型。
除了 Denis V 的正确答案之外,我想补充一点,您还可以像这样修改您的控制器:
public function addPanier(Request $request, Environment $twig, RegistryInterface $doctrine,ProduitRepository $produitRepository, $id)
{
$produitSelected = $produitRepostiory->find($id);
//rest of the code
}
这样 phpstorm 也知道返回对象的类型,因为每个返回的对象在相应的存储库中都有类型提示。
您首先需要修复代码:
不要注入 $id,你只需要输入你的实体:https://symfony.com/doc/current/best_practices/controllers.html#using-the-paramconverter
不要注入$doctrine,使用$em = $this->getDoctrine()->getManager();
不要注入 $twig,使用 return $this->render('...template', []);
使用英文,始终是规则。不仅其他人可以帮助你,而且因为 Symfony 理解它,当你开始使用表单集合时你将需要它:https://symfony.com/doc/current/form/form_collections.html
注入存储库,您将拥有自动完成功能并更容易发现错误。使用```make:entity``命令,你会看到我的想法,很难解释。
多亏了 symfony 文档 https://symfony.com/doc/current/doctrine.html#updating-an-object,我能够使用名为 'Produit'.
的实体中的 get/set 方法但是当我调用方法 setProduit()(来自 Paniers 实体)时,Phpstorm 为 $produitSelected 说 "expected App\Entity\Paniers, got Object"。
我不知道为什么 phpstorm 说因为我能够使用方法,有什么问题? find() return 一个实体对象,对吧?
class PaniersController extends AbstractController
{
/**
* @Route("/paniers/add/{id}", name="paniers.add")
*/
public function addPanier(Request $request, Environment $twig, RegistryInterface $doctrine, $id)
{
$produitSelected = $doctrine->getRepository(Produit::class)->find($id);
if (!$produitSelected) {
throw $this->createNotFoundException(
'Pas de produit trouvé pour l\' id : '.$id
);
}
$lignePanier=$doctrine->getRepository(Paniers::class)->findOneBy(['produit' => $produitSelected, 'user' =>$this->getUser()]);
if($produitSelected->getStock()>0){
if ($lignePanier){
$quantite =$lignePanier->getQuantite();
$lignePanier->setQuantite($quantite+1);
} else {
$lignePanier = new Paniers();
$lignePanier->setUser($this->getUser())
->setDateAjoutPanier(new \DateTime(date('Y-m-d')))
->setQuantite(1)
->setProduit($produitSelected);
}
$doctrine->getManager()->persist($lignePanier);
$produitSelected->setStock($produitSelected->getStock()-1);
$doctrine->getManager()->persist($produitSelected);
$doctrine->getManager()->flush();
}
}
}
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\PaniersRepository")
* @ORM\Table(name="paniers")
*/
class Paniers
{
//...
/**
* @ORM\ManyToOne(targetEntity="Produit")
* @ORM\JoinColumn(name="produit_id", referencedColumnName="id")
*/
private $produit;
public function getProduit(): ?Produit
{
return $this->produit;
}
public function setProduit(?Produit $produit): self
{
$this->produit = $produit;
return $this;
}
}
PhpStorm 显然没有那么聪明,无法理解在这种情况下 find($id)
的 return 值的实际类型将是 Produit
。但你可以帮助它:
/** @var Produit $produitSelected */
$produitSelected = $doctrine->getRepository(Produit::class)->find($id);
要使其正常工作,您应该将 Produit
与完整命名空间一起使用,或者直接在类型提示中添加命名空间。
当然这不能保证或确定实际类型将是 Produit
。所以,如果你犯了错误,PhpStorm 会报告错误的类型。
除了 Denis V 的正确答案之外,我想补充一点,您还可以像这样修改您的控制器:
public function addPanier(Request $request, Environment $twig, RegistryInterface $doctrine,ProduitRepository $produitRepository, $id)
{
$produitSelected = $produitRepostiory->find($id);
//rest of the code
}
这样 phpstorm 也知道返回对象的类型,因为每个返回的对象在相应的存储库中都有类型提示。
您首先需要修复代码:
不要注入 $id,你只需要输入你的实体:https://symfony.com/doc/current/best_practices/controllers.html#using-the-paramconverter
不要注入$doctrine,使用$em = $this->getDoctrine()->getManager();
不要注入 $twig,使用 return $this->render('...template', []);
使用英文,始终是规则。不仅其他人可以帮助你,而且因为 Symfony 理解它,当你开始使用表单集合时你将需要它:https://symfony.com/doc/current/form/form_collections.html
注入存储库,您将拥有自动完成功能并更容易发现错误。使用```make:entity``命令,你会看到我的想法,很难解释。