Symfony2 - 数组到字符串转换错误

Posted

技术标签:

【中文标题】Symfony2 - 数组到字符串转换错误【英文标题】:Symfony2 - array to string conversion error 【发布时间】:2013-06-23 07:01:27 【问题描述】:

我已经阅读了其他主题,但它并没有解决我的问题,所以:

我有这个

->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  +

【问题讨论】:

请提供完整的堆栈跟踪 - 否则没有人可以看到错误的真正来源 已提供完整堆栈跟踪 顺便说一句,只有当我将 mapped 设置为 true(现在)时才会发生这种情况 mapped true 是默认值——你可以省略它。如果您不想将值添加到表单的基础实体,则只需将其设置为 false。 如果省略 "mapped" 会发生什么? 【参考方案1】:

Symfony 试图将你的 $role(array property) 转换为 not multiple 选择字段(string)。

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

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

例子:

<?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

【讨论】:

当我获得足够的声望时,我一定会的 值得注意的是,这个答案特别适用于数组。如果表单引用了一个对象(例如,我的情况是一个 User 对象),则转换器需要从 User 对象引用。例如,在转换器中,我在“转换”函数中使用了 $user->getRoles()[0]。 您的解决方案是正确的。但是,这没有任何意义。如果您的解决方案是基于丢失数据,这是不可接受的。 @user2394156 您只需要对 ORM 文件进行一点更改。确保您的字段是数组或 json_array。依此类推,Symfony2 会将您的数据作为序列化或 json 数据插入到数据库列中。【参考方案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";

【讨论】:

【参考方案3】:

我只是添加一个 DataTransformer 而不改变我的角色属性的数组类型然后我把它放在我的 UserType 中:

use AppBundle\Form\DataTransformer\StringToArrayTransformer;

//...

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

它对我有用。

【讨论】:

【参考方案4】:

我有你的问题.. 我用这个解决方案解决了这个问题。希望对你有帮助

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

用户实体

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',
            ]
        ))

【讨论】:

以上是关于Symfony2 - 数组到字符串转换错误的主要内容,如果未能解决你的问题,请参考以下文章

选择表单类型的数组到字符串转换错误

symfony2 ContextErrorException:可捕获的致命错误:类 Proxies\__CG__\...\Entity\... 的对象无法转换为字符串

protobuf转换的数组传进scoket中类型转换错误

在 Laravel 5.8.38 中上传多个文件时数组到字符串的转换错误

C#如何将OBJECT转换成数组

laravel - ErrorException 数组到字符串的转换