24

I've read the other subjects but it doesn't solve my problem so:

I've got this

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

And whatever I do, I get this error:

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

In my form type the setRole method is not even called (when I rename it to some garbage the error still occurs). Why is this happening?

// EDIT

Full stack trace:

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  +
8
  • please provide the full stack trace - otherwise nobody can see where the error has it's real source Commented Jun 26, 2013 at 8:24
  • 1
    Full stack trace has been provided Commented Jun 26, 2013 at 8:29
  • By the way it happens only when I set mapped to true (which is now) Commented Jun 26, 2013 at 8:32
  • mapped true is the default value - you could ommit it. it's only necessary to put it to false if you don't want to add the values to the underlying entity of the form. Commented Jun 26, 2013 at 8:34
  • what happens if you ommit "mapped" ? Commented Jun 26, 2013 at 8:37

4 Answers 4

40

Symfony's trying to convert your $role(array property) to not multiple choice field(string).

There's several ways to deal with this problem:

  1. Set multiple to true in your choice form widget.
  2. Change mapping from array to string for $role property in your entity.
  3. If you insist to have above options unchanged, you can create DataTransformer. That's not the best solution because you will lose data if your array have more than 1 element.

Example:

<?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);
    }
}

And then in your form class:

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));

You can read more about DataTransformers here: http://symfony.com/doc/current/cookbook/form/data_transformers.html

Sign up to request clarification or add additional context in comments.

3 Comments

I will when I get enough reputation, for sure
It might be worth noting that this answer works specifically on an array. If the form is referencing an object (eg. a User object as was my case), the transformer needs to reference from the User object. For example, in the transformer I used $user->getRoles()[0] in the "transform" function.
Your solution is true. However, it does not make sense. If your solution is based on losing data, it is not acceptable. @user2394156 You need only little bit change on your ORM file. Make sure that your field is array or json_array. So on, Symfony2 will insert your data as serialized or json data to database column.
2

Make sure that you use proper data type in ORM file. In this case, your role field cannot be string. It must be a many-to-many relation, array or json_array.

If you choose one of them, symfony will insert the data without effort or any type of transformer.

E.g.:

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

So, it will live in your database as like:

a:2:{i:0;s:4:"user";i:1;s:5:"admin";}

Comments

1

I just add a DataTransformer without changing the array type of my roles attribute then I put this in my UserType :

use AppBundle\Form\DataTransformer\StringToArrayTransformer;

//...

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

And it works for me.

Comments

1

I have your problem .. I solved this with this solution. I hope it helps you

this code work's on login and register form ...

user entity

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;
    }

UserType

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.