Symfony2 - 数组转字符串错误

24

我已经阅读了其他相关主题,但它们并不能解决我的问题,所以:

我有这个

->add('role', 'choice', array(
                'label' => 'I am:',
                'mapped' => true,
                'expanded' => true,
                'multiple' => false,
                'choices' => array(
                    'ROLE_NORMAL' => 'Standard',
                    'ROLE_VIP' => 'VIP',
                ) 
            ))

无论我做什么,都会出现这个错误:

Notice: Array to string conversion in C:\xampp\htdocs\xxx\vendor\symfony\symfony  \src\Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList.php line 458 

在我的表单类型中,即使我将setRole方法重命名为一些垃圾名称,该方法也没有被调用。为什么会发生这种情况?

// 编辑

完整的堆栈跟踪:

in C:\xampp\htdocs\xxx\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList.php at line 458  -

     */
    protected function fixIndex($index)
    {
        if (is_bool($index) || (string) (int) $index === (string) $index) {
            return (int) $index;
        }

    at ErrorHandler ->handle ('8', 'Array to string conversion', 'C:\xampp\htdocs     \xxx\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList.php', '458', array('index' => array()))
in C:\xampp\htdocs\xxx\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList.php at line 458  +
at ChoiceList ->fixIndex (array())
in C:\xampp\htdocs\xxx\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList.php at line 476  +
at ChoiceList ->fixIndices (array(array()))
in C:\xampp\htdocs\xxx\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\ChoiceList\SimpleChoiceList.php at line 152  +
at SimpleChoiceList ->fixChoices (array(array()))
in C:\xampp\htdocs\xxx\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList.php at line 204  +
at ChoiceList ->getIndicesForChoices (array(array()))
in C:\xampp\htdocs\xxx\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\DataTransformer\ChoiceToBooleanArrayTransformer.php at line 63  +
at ChoiceToBooleanArrayTransformer ->transform (array())
in C:\xampp\htdocs\xxx\vendor\symfony\symfony\src\Symfony\Component\Form\Form.php at line 1019  +
at Form ->normToView (array())
in C:\xampp\htdocs\xxx\vendor\symfony\symfony\src\Symfony\Component\Form\Form.php at line 332  +
at Form ->setData (array())
in C:\xampp\htdocs\xxx\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper.php at line 59  +
at PropertyPathMapper ->mapDataToForms (object(User), object(RecursiveIteratorIterator))
in C:\xampp\htdocs\xxx\vendor\symfony\symfony\src\Symfony\Component\Form\Form.php at line 375  +
at Form ->setData (object(User))
in C:\xampp\htdocs\xxx\vendor\friendsofsymfony\user-bundle\FOS\UserBundle\Controller\RegistrationController.php at line 49  +
at RegistrationController ->registerAction (object(Request))
at call_user_func_array (array(object(RegistrationController), 'registerAction'), array(object(Request)))
in C:\xampp\htdocs\xxx\app\bootstrap.php.cache at line 2770  +
at HttpKernel ->handleRaw (object(Request), '1')
in C:\xampp\htdocs\xxx\app\bootstrap.php.cache at line 2744  +
at HttpKernel ->handle (object(Request), '1', true)
in C:\xampp\htdocs\xxx\app\bootstrap.php.cache at line 2874  +
at ContainerAwareHttpKernel ->handle (object(Request), '1', true)
in C:\xampp\htdocs\xxx\app\bootstrap.php.cache at line 2175  +
at Kernel ->handle (object(Request))
in C:\xampp\htdocs\xxx\web\app_dev.php at line 29  +

1
已提供完整的堆栈跟踪 - user2394156
顺便提一下,只有当我将映射设置为true时(现在是这样),才会发生这种情况。 - user2394156
mapped true是默认值 - 你可以省略它。只有当你不想将这些值添加到表单的基础实体时,才需要将其设置为false。 - Nicolai Fröhlich
与上面显示的完全相同的错误。 - user2394156
请问您可以添加您的实体吗? - Nicolai Fröhlich
显示剩余3条评论
4个回答

40

Symfony试图将您的$role(数组属性)转换为非多选字段(字符串)。

有几种方法可以解决这个问题:

  1. 在您的选择表单小部件中将multiple设置为true
  2. 更改实体中$role属性的映射,从array更改为string
  3. 如果您坚持不改变上述选项,可以创建DataTransformer。 这不是最好的解决方案,因为如果您的数组有多个元素,您丢失数据

示例:

<?php
namespace Acme\DemoBundle\Form\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;

class StringToArrayTransformer implements DataTransformerInterface
{
    /**
     * Transforms an array to a string. 
     * POSSIBLE LOSS OF DATA
     *
     * @return string
     */
    public function transform($array)
    {
        return $array[0];
    }

    /**
     * Transforms a string to an array.
     *
     * @param  string $string
     *
     * @return array
     */
    public function reverseTransform($string)
    {
        return array($string);
    }
}

然后在您的表单类中:

use Acme\DemoBundle\Form\DataTransformer\StringToArrayTransformer;
/* ... */
$transformer = new StringToArrayTransformer();
$builder->add($builder->create('role', 'choice', array(
                'label' => 'I am:',
                'mapped' => true,
                'expanded' => true,
                'multiple' => false,
                'choices' => array(
                    'ROLE_NORMAL' => 'Standard',
                    'ROLE_VIP' => 'VIP',
                )
              ))->addModelTransformer($transformer));

您可以在此处阅读有关DataTransformers的更多信息:http://symfony.com/doc/current/cookbook/form/data_transformers.html


1
当我获得足够的声望时,我肯定会这样做。 - user2394156
1
值得注意的是,此答案仅适用于数组。如果表单引用了一个对象(例如,像我的情况一样引用了一个用户对象),则转换器需要从用户对象中引用。例如,在转换器中,我在“transform”函数中使用了$user->getRoles()[0]。 - Ryan B
你的解决方案是正确的。然而,它并不合理。如果你的解决方案基于数据丢失,那么它是不可接受的。@user2394156 你只需要在ORM文件上做一点小改动。确保你的字段是数组或json_array。这样,Symfony2将把你的数据作为序列化或json数据插入到数据库列中。 - Ali Emre Çakmakoğlu

2

请确保在ORM文件中使用正确的数据类型。在这种情况下,您的角色字段不能是字符串。它必须是多对多关系、数组或json_array。

如果您选择其中之一,Symfony将无需任何转换器的帮助插入数据。

例如:

// Resources/config/User.orm.yml
fields:
  role:
      type: array
      nullable: false

所以,它将在您的数据库中存储如下:
a:2:{i:0;s:4:"user";i:1;s:5:"admin";}

1

我只是添加了一个 DataTransformer,而没有改变我的 roles 属性的数组类型,然后我将其放入我的 UserType 中:

use AppBundle\Form\DataTransformer\StringToArrayTransformer;

//...

$transformer = new StringToArrayTransformer();    
$builder->get('roles')->addModelTransformer($transformer);

"对我来说它有效。",保留HTML标签不解释。

1

我理解您的问题.. 我用以下解决方案解决了它。希望能对您有所帮助。

这段代码适用于登录和注册表单...

用户实体

class User {
    /**
     * @ORM\Column(type="array")
     */
    private $roles ;

    public function getRoles()
    {
        $roles = $this->roles;
         var_dump($roles);
        if ($roles != NULL) {
            return explode(" ",$roles);
        }else {
           return $this->roles;
        }
    }


  public function setRoles($roles)
    {
        $this->roles = $roles;
    }

用户类型
 ->add('roles', ChoiceType::class, array(
            'attr' => array(
                'class' => 'form-control',
                'value' => $options[0]['roles'],
                'required' => false,
            ),
            'multiple' => true,
            'expanded' => true, // render check-boxes
            'choices' => [
                'admin' => 'ROLE_ADMIN',
                'user' => 'ROLE_USER',
            ]
        ))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接