Symfony 3 表单集合调用非对象上的成员函数 add()
Symfony 3 form collection Call to a member function add() on a non-object
我正在尝试了解如何在 sf 3 中使用表单集合,但我在遵循 sf 网站的教程时遇到了问题,因为它给我带来了错误,我设法理解了我做错了什么我希望你能帮助我。
要约实体
<?php
namespace Zenith\OfferGeneratorBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\Common\Collections\ArrayCollection;
use Zenith\productsBundle\Entity\products;
/**
* Offer
*
* @ORM\Table(name="offer")
* @ORM\Entity(repositoryClass="Zenith\OfferGeneratorBundle\Repository\OfferRepository")
*/
class Offer
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @var string
*
* @ORM\ManyToMany(targetEntity="ProductCollection", inversedBy="offer", cascade={"persist"})
*/
private $products;
/**
* @var \DateTime
*
* @Gedmo\Timestampable(on="create")
* @ORM\Column(name="createdAt", type="datetime")
*/
private $createdAt;
/**
* @var \DateTime
*
* @Gedmo\Timestampable(on="update")
* @ORM\Column(name="modifiedAt", type="datetime")
*/
private $modifiedAt;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return Offer
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set createdAt
*
* @param \DateTime $createdAt
*
* @return Offer
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* Get createdAt
*
* @return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* Set modifiedAt
*
* @param \DateTime $modifiedAt
*
* @return Offer
*/
public function setModifiedAt($modifiedAt)
{
$this->modifiedAt = $modifiedAt;
return $this;
}
/**
* Get modifiedAt
*
* @return \DateTime
*/
public function getModifiedAt()
{
return $this->modifiedAt;
}
/**
* Add product
*
* @param \Zenith\OfferGeneratorBundle\Entity\ProductCollection $product
*
* @return Offer
*/
public function addProduct(ProductCollection $product)
{
$product->addOffer($this);
$this->products->add($product);
}
/**
* Remove product
*
* @param \Zenith\OfferGeneratorBundle\Entity\ProductCollection $product
*/
public function removeProduct(\Zenith\OfferGeneratorBundle\Entity\ProductCollection $product)
{
$this->products->removeElement($product);
}
/**
* Get products
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getProducts()
{
return $this->products;
}
}
ProductCollection 实体
<?php
namespace Zenith\OfferGeneratorBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Product
*
* @ORM\Table( )
* @ORM\Entity(repositoryClass="Zenith\OfferGeneratorBundle\Repository\ProductRepository")
*/
class ProductCollection
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @var int
*
* @ORM\Column(name="price", type="integer")
*/
private $price;
/**
* @var int
*
* @ORM\Column(name="quantity", type="integer")
*/
private $quantity;
/**
* @var string
*
* @ORM\ManyToMany(targetEntity="Offer", mappedBy="products")
*/
private $offer;
/**
* @var int
*
* @ORM\ManyToMany(targetEntity="Zenith\ProductBundle\Entity\Product")
*/
private $product;
/**
* Constructor
*/
public function __construct()
{
$this->offer = new \Doctrine\Common\Collections\ArrayCollection();
$this->product = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return ProductCollection
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set price
*
* @param integer $price
*
* @return ProductCollection
*/
public function setPrice($price)
{
$this->price = $price;
return $this;
}
/**
* Get price
*
* @return integer
*/
public function getPrice()
{
return $this->price;
}
/**
* Set quantity
*
* @param integer $quantity
*
* @return ProductCollection
*/
public function setQuantity($quantity)
{
$this->quantity = $quantity;
return $this;
}
/**
* Get quantity
*
* @return integer
*/
public function getQuantity()
{
return $this->quantity;
}
/**
* Add offer
*
* @param \Zenith\OfferGeneratorBundle\Entity\Offer $offer
*
* @return ProductCollection
*/
public function addOffer(\Zenith\OfferGeneratorBundle\Entity\Offer $offer)
{
if (!$this->offer->contains($offer)) {
$this->offer->add($offer);
}
}
/**
* Remove offer
*
* @param \Zenith\OfferGeneratorBundle\Entity\Offer $offer
*/
public function removeOffer(\Zenith\OfferGeneratorBundle\Entity\Offer $offer)
{
$this->offer->removeElement($offer);
}
/**
* Get offer
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getOffer()
{
return $this->offer;
}
/**
* Add product
*
* @param \Zenith\ProductBundle\Entity\Product $product
*
* @return ProductCollection
*/
public function addProduct(\Zenith\ProductBundle\Entity\Product $product)
{
$this->product[] = $product;
return $this;
}
/**
* Remove product
*
* @param \Zenith\ProductBundle\Entity\Product $product
*/
public function removeProduct(\Zenith\ProductBundle\Entity\Product $product)
{
$this->product->removeElement($product);
}
/**
* Get product
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getProduct()
{
return $this->product;
}
}
当我尝试在提交后使用表单添加内容时,出现以下错误。
Error: Call to a member function add() on a non-object
500 Internal Server Error - FatalErrorException
堆栈跟踪:
{
$product->addOffer($this);
$this->products->add($product);
}
/**
根据此处的一个答案,我更改了代码,但我收到另一个错误,我认为它来自我在其中一个字段上使用的数据转换器。
<?php
namespace Zenith\OfferGeneratorBundle\Form\DataTransformer;
use Zenith\ProductBundle\Entity\Product;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
class ProductNameTransformer implements DataTransformerInterface
{
private $manager;
public function __construct(ObjectManager $manager)
{
$this->manager = $manager;
}
/**
* Transforms an object (issue) to a string (number).
*
* @param Issue|null $issue
* @return string
*/
public function transform($issue)
{
if (null === $issue) {
return '';
}
return $issue->getId();
}
/**
* Transforms a string (number) to an object (issue).
*
* @param string $issueNumber
* @return Issue|null
* @throws TransformationFailedException if object (issue) is not found.
*/
public function reverseTransform($issueNumber)
{
// no issue number? It's optional, so that's ok
if (!$issueNumber) {
return;
}
$issue = $this->manager
->getRepository('ProductBundle:Product')
// query for the issue with this id
->findByName($issueNumber)
;
if (null === $issue) {
// causes a validation error
// this message is not shown to the user
// see the invalid_message option
throw new TransformationFailedException(sprintf(
'An issue with number "%s" does not exist!',
$issueNumber
));
}
return $issue;
}
}
Notice: Array to string conversion
500 Internal Server Error - ContextErrorException
Stack Trace
in vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php at line 67 -
public function bindValue($param, $value, $type = \PDO::PARAM_STR)
{
try {
return parent::bindValue($param, $value, $type);
} catch (\PDOException $exception) {
throw new PDOException($exception);
}
at ErrorHandler ->handleError ('8', 'Array to string conversion', '/var/www/f.dev/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php', '67', array('param' => '1', 'value' => array(object(Product)), 'type' => '2'))
at PDOStatement ->bindValue ('1', array(object(Product)), '2')
in vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php at line 67 +
at PDOStatement ->bindValue ('1', array(object(Product)), '2')
in vendor/doctrine/dbal/lib/Doctrine/DBAL/Statement.php at line 120 +
at Statement ->bindValue ('1', array(object(Product)), 'string')
in vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php at line 277 +
at BasicEntityPersister ->executeInserts ()
in vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php at line 1018 +
at UnitOfWork ->executeInserts (object(ClassMetadata))
in vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php at line 378 +
at UnitOfWork ->commit (null)
in vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php at line 356 +
at EntityManager ->flush ()
in src/Zenith/OfferGeneratorBundle/Controller/OfferController.php at line 118 +
at OfferController ->newOfferSubmitedAction (object(Request))
at call_user_func_array (array(object(OfferController), 'newOfferSubmitedAction'), array(object(Request)))
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php at line 139 +
at HttpKernel ->handleRaw (object(Request), '1')
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php at line 62 +
at HttpKernel ->handle (object(Request), '1', true)
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php at line 169 +
at Kernel ->handle (object(Request))
in web/app_dev.php at line 30 +
您需要在 __construct
中初始化您的产品集合,否则您将尝试调用 add
空值(产品将被初始化为空值)。
public function __construct()
{
$this->products = new ArrayCollection();
}
我正在尝试了解如何在 sf 3 中使用表单集合,但我在遵循 sf 网站的教程时遇到了问题,因为它给我带来了错误,我设法理解了我做错了什么我希望你能帮助我。
要约实体
<?php
namespace Zenith\OfferGeneratorBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\Common\Collections\ArrayCollection;
use Zenith\productsBundle\Entity\products;
/**
* Offer
*
* @ORM\Table(name="offer")
* @ORM\Entity(repositoryClass="Zenith\OfferGeneratorBundle\Repository\OfferRepository")
*/
class Offer
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @var string
*
* @ORM\ManyToMany(targetEntity="ProductCollection", inversedBy="offer", cascade={"persist"})
*/
private $products;
/**
* @var \DateTime
*
* @Gedmo\Timestampable(on="create")
* @ORM\Column(name="createdAt", type="datetime")
*/
private $createdAt;
/**
* @var \DateTime
*
* @Gedmo\Timestampable(on="update")
* @ORM\Column(name="modifiedAt", type="datetime")
*/
private $modifiedAt;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return Offer
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set createdAt
*
* @param \DateTime $createdAt
*
* @return Offer
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* Get createdAt
*
* @return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* Set modifiedAt
*
* @param \DateTime $modifiedAt
*
* @return Offer
*/
public function setModifiedAt($modifiedAt)
{
$this->modifiedAt = $modifiedAt;
return $this;
}
/**
* Get modifiedAt
*
* @return \DateTime
*/
public function getModifiedAt()
{
return $this->modifiedAt;
}
/**
* Add product
*
* @param \Zenith\OfferGeneratorBundle\Entity\ProductCollection $product
*
* @return Offer
*/
public function addProduct(ProductCollection $product)
{
$product->addOffer($this);
$this->products->add($product);
}
/**
* Remove product
*
* @param \Zenith\OfferGeneratorBundle\Entity\ProductCollection $product
*/
public function removeProduct(\Zenith\OfferGeneratorBundle\Entity\ProductCollection $product)
{
$this->products->removeElement($product);
}
/**
* Get products
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getProducts()
{
return $this->products;
}
}
ProductCollection 实体
<?php
namespace Zenith\OfferGeneratorBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Product
*
* @ORM\Table( )
* @ORM\Entity(repositoryClass="Zenith\OfferGeneratorBundle\Repository\ProductRepository")
*/
class ProductCollection
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @var int
*
* @ORM\Column(name="price", type="integer")
*/
private $price;
/**
* @var int
*
* @ORM\Column(name="quantity", type="integer")
*/
private $quantity;
/**
* @var string
*
* @ORM\ManyToMany(targetEntity="Offer", mappedBy="products")
*/
private $offer;
/**
* @var int
*
* @ORM\ManyToMany(targetEntity="Zenith\ProductBundle\Entity\Product")
*/
private $product;
/**
* Constructor
*/
public function __construct()
{
$this->offer = new \Doctrine\Common\Collections\ArrayCollection();
$this->product = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return ProductCollection
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set price
*
* @param integer $price
*
* @return ProductCollection
*/
public function setPrice($price)
{
$this->price = $price;
return $this;
}
/**
* Get price
*
* @return integer
*/
public function getPrice()
{
return $this->price;
}
/**
* Set quantity
*
* @param integer $quantity
*
* @return ProductCollection
*/
public function setQuantity($quantity)
{
$this->quantity = $quantity;
return $this;
}
/**
* Get quantity
*
* @return integer
*/
public function getQuantity()
{
return $this->quantity;
}
/**
* Add offer
*
* @param \Zenith\OfferGeneratorBundle\Entity\Offer $offer
*
* @return ProductCollection
*/
public function addOffer(\Zenith\OfferGeneratorBundle\Entity\Offer $offer)
{
if (!$this->offer->contains($offer)) {
$this->offer->add($offer);
}
}
/**
* Remove offer
*
* @param \Zenith\OfferGeneratorBundle\Entity\Offer $offer
*/
public function removeOffer(\Zenith\OfferGeneratorBundle\Entity\Offer $offer)
{
$this->offer->removeElement($offer);
}
/**
* Get offer
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getOffer()
{
return $this->offer;
}
/**
* Add product
*
* @param \Zenith\ProductBundle\Entity\Product $product
*
* @return ProductCollection
*/
public function addProduct(\Zenith\ProductBundle\Entity\Product $product)
{
$this->product[] = $product;
return $this;
}
/**
* Remove product
*
* @param \Zenith\ProductBundle\Entity\Product $product
*/
public function removeProduct(\Zenith\ProductBundle\Entity\Product $product)
{
$this->product->removeElement($product);
}
/**
* Get product
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getProduct()
{
return $this->product;
}
}
当我尝试在提交后使用表单添加内容时,出现以下错误。
Error: Call to a member function add() on a non-object
500 Internal Server Error - FatalErrorException
堆栈跟踪:
{
$product->addOffer($this);
$this->products->add($product);
}
/**
根据此处的一个答案,我更改了代码,但我收到另一个错误,我认为它来自我在其中一个字段上使用的数据转换器。
<?php
namespace Zenith\OfferGeneratorBundle\Form\DataTransformer;
use Zenith\ProductBundle\Entity\Product;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
class ProductNameTransformer implements DataTransformerInterface
{
private $manager;
public function __construct(ObjectManager $manager)
{
$this->manager = $manager;
}
/**
* Transforms an object (issue) to a string (number).
*
* @param Issue|null $issue
* @return string
*/
public function transform($issue)
{
if (null === $issue) {
return '';
}
return $issue->getId();
}
/**
* Transforms a string (number) to an object (issue).
*
* @param string $issueNumber
* @return Issue|null
* @throws TransformationFailedException if object (issue) is not found.
*/
public function reverseTransform($issueNumber)
{
// no issue number? It's optional, so that's ok
if (!$issueNumber) {
return;
}
$issue = $this->manager
->getRepository('ProductBundle:Product')
// query for the issue with this id
->findByName($issueNumber)
;
if (null === $issue) {
// causes a validation error
// this message is not shown to the user
// see the invalid_message option
throw new TransformationFailedException(sprintf(
'An issue with number "%s" does not exist!',
$issueNumber
));
}
return $issue;
}
}
Notice: Array to string conversion
500 Internal Server Error - ContextErrorException
Stack Trace
in vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php at line 67 -
public function bindValue($param, $value, $type = \PDO::PARAM_STR)
{
try {
return parent::bindValue($param, $value, $type);
} catch (\PDOException $exception) {
throw new PDOException($exception);
}
at ErrorHandler ->handleError ('8', 'Array to string conversion', '/var/www/f.dev/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php', '67', array('param' => '1', 'value' => array(object(Product)), 'type' => '2'))
at PDOStatement ->bindValue ('1', array(object(Product)), '2')
in vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php at line 67 +
at PDOStatement ->bindValue ('1', array(object(Product)), '2')
in vendor/doctrine/dbal/lib/Doctrine/DBAL/Statement.php at line 120 +
at Statement ->bindValue ('1', array(object(Product)), 'string')
in vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php at line 277 +
at BasicEntityPersister ->executeInserts ()
in vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php at line 1018 +
at UnitOfWork ->executeInserts (object(ClassMetadata))
in vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php at line 378 +
at UnitOfWork ->commit (null)
in vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php at line 356 +
at EntityManager ->flush ()
in src/Zenith/OfferGeneratorBundle/Controller/OfferController.php at line 118 +
at OfferController ->newOfferSubmitedAction (object(Request))
at call_user_func_array (array(object(OfferController), 'newOfferSubmitedAction'), array(object(Request)))
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php at line 139 +
at HttpKernel ->handleRaw (object(Request), '1')
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php at line 62 +
at HttpKernel ->handle (object(Request), '1', true)
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php at line 169 +
at Kernel ->handle (object(Request))
in web/app_dev.php at line 30 +
您需要在 __construct
中初始化您的产品集合,否则您将尝试调用 add
空值(产品将被初始化为空值)。
public function __construct()
{
$this->products = new ArrayCollection();
}