【问题标题】:Symfony3 form checkbox save errorSymfony3 表单复选框保存错误
【发布时间】:2017-11-18 12:35:21
【问题描述】:

我尝试在 Google 上查找,但没有找到遇到此类问题的人。我想我所做的一切都像文档指南一样,但我想我错过了一些东西

所以我有一个这样的复选框:

    $builder->add(
        'productTypes',
        EntityType::class,
        array(
            'label'        => 'Available for products',
            'class'        => 'ShopBundle:ProductType',
            'choice_label' => 'name',
            'multiple'     => true,
            'expanded'     => true,
            'by_reference' => false,
        )
    );

当我编辑一切顺利时,我可以编辑现有条目并选中或取消选中此复选框,它可以正确保存,但是当我尝试添加新对象时出现错误:

PHP 致命错误:在 null 上调用成员函数 add() C:\xampp\htdocs\uniacar-sf\src\ShopBundle\Entity\ProductAttribute.php 在第 188 行

这是我的控制器操作:

public function editAction(Request $request, $id = null)
{
    $this->setMenuTab('cars', 'admin');
    $productTypes = new ArrayCollection();

    if (!empty($id)) {
        $attribute = $this->getRepo(ProductAttribute::class)->find($id);
        $this->setTitle('admin.cars.attributes.edit');

        foreach ($attribute->getProductTypes() as $value) {
            $productTypes->add($value);
        }
    } else {
        $attribute = new ProductAttribute();
        $this->setTitle('admin.cars.attributes.new');
    }

    $form = $this->createForm(ProductAttributeForm::class, $attribute);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $attribute = $form->getData();

        foreach ($productTypes as $productType) {
            if (false === $attribute->getProductTypes()->contains($productType)) {
                $productType->getAttributes()->removeElement($attribute);
                $this->db()->persist($productType);
            }
        }

        $this->db()->persist($attribute);
        $this->db()->flush();

        return $this->redirectToRoute('carAdmin', array('tab' => 'attributes'));
    }

    $this->setVariables(
        array(
            'form'      => $form->createView(),
            'attribute' => $attribute,
        )
    );

    return $this->response();
}

$this->db()$this->getDoctrine()->getManager() 的快捷方式

这是 ProductAttribute 中与 ProductType 相关的定义部分:

/**
 * Constructor
 */
public function __construct() {
    $this->productTypes = new ArrayCollection();
}

/**
 * Many Attributes have Many ProductTypes
 * @ORM\ManyToMany(targetEntity="ProductType", mappedBy="attributes", cascade={"persist"})
 */
private $productTypes;

/**
 * @param ProductType $productType
 */
public function addProductType(ProductType $productType)
{
    $this->productTypes->add($productType);
    $productType->addProductAttribute($this);
}

/**
 * @param ProductType $productType
 */
public function removeProductType(ProductType $productType)
{
    $this->productTypes->removeElement($productType);
}

还有一部分 ProductType Entity 与 ProductAttribute 相关:

/**
 * Constructor
 */
public function __construct() {
    $this->attributes = new ArrayCollection();
}

/**
 * Many ProductTypes have Many Attributes
 * @ORM\ManyToMany(targetEntity="ProductAttribute", inversedBy="productTypes")
 * @ORM\JoinTable(name="product_type_to_attribute")
 */
private $attributes;


/**
 * @param ProductAttribute $attribute
 */
public function addProductAttribute(ProductAttribute $attribute)
{
    if (!$this->attributes->contains($attribute)) {
        $this->attributes->add($attribute);
    }
}

public function removeProductAttribute(ProductAttribute $attribute)
{
    $this->attributes->removeElement($attribute);
}

我尝试遵循 Symfony 嵌入表单教程 (How to Embed a Collection of Forms) 我知道在这种情况下没有嵌入集合(我在这个实体中有另一个字段,即嵌入的表单集合,它工作得很好)但据我所知,在这种情况下关系是相同的,它是多对多的我必须告诉 Symfony 如何处理关系、添加和删除对象。 我转储了 POST 中的数据,但它与版本相同 - productType 在那里。任何想法为什么我会收到此错误?

它在 $this->productTypes->add($productType); 行中的 ProductAttribute 实体中触发

编辑: 我更新了控制器代码,我弄乱了从 ProductAttribute 中取消链接 ProductType 的逻辑。但这对问题没有任何影响,当我尝试保存新对象时仍然是同样的 500 错误。

编辑2: 我无法从 Symfony 获取堆栈跟踪,因为我得到普通的浏览器 500 错误(可能是因为它是致命错误,我在 apache 日志中找到了它)。控制器中产生错误的行是$form->handleRequest($request);

【问题讨论】:

  • 你能告诉我们,它在控制器的哪一行中断了吗?在处理请求时,在冲洗时,在其他地方?
  • 它在实体中中断,在我在帖子末尾提到的方法 addProductType 中
  • 我知道它打破了实体。但是由于控制器中的某些行,它进入了实体。你能告诉我们它在控制器中的哪一行吗?或者附加完整的堆栈跟踪。
  • 我无法获得堆栈跟踪,尽管应用程序在开发模式下运行且调试设置为 true,但出现浏览器典型 500 错误,我仅在 apache 日志中发现导致此错误的行。这种错误以前从未发生在我身上,我想这是因为Symfony无法将堆栈跟踪转储给我的致命错误..
  • addProductType() 在哪里被调用?

标签: php forms symfony checkbox doctrine


【解决方案1】:

这不是表单集合,但您使用的是集合特定方法,这不是一个好习惯,但是,当您创建新对象时,您不需要下面的代码。

foreach ($productTypes as $value) {
    if (false === $attribute->getProductTypes()->contains($value)) {
            $attribute->getProductTypes()->removeElement($value);
    }
}

【讨论】:

  • 我需要它,没有它我无法取消链接(我的意思是当我取消选中复选框并保存时,它仍然保持连接状态)。哦,你的意思是在创建对象时......当我创建对象时,$productTypes 数组是空的,所以这部分代码没有任何反应。
  • 我也刚刚注意到,突然间即使使用它我也无法从 ProductAttribute 中取消链接 ProductType.. 昨天完全相同的代码已经不同了.. 现在我什么都不知道了 :(
  • 好的,很抱歉垃圾邮件。您为我指明了正确的方向,我弄乱了逻辑并尝试仅在该元素不在集合中的情况下才删除元素(原文如此!),现在控制器代码已使用正确的逻辑进行了修复:)
【解决方案2】:

所以,我还没有找到问题的解决方案,但我通过修复我的项目的文件结构以某种方式解决了它(将包的资源从通用资源文件夹移动到包的资源文件夹)。我不知道为什么这解决了这个问题,甚至工作但不正确的文件夹结构和提交表单之间有什么联系,但现在它可以工作了,所以我会将问题标记为已回答。

【讨论】:

    猜你喜欢
    • 2018-03-18
    • 2016-11-12
    • 2012-02-24
    • 2017-09-27
    • 1970-01-01
    • 2023-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多