Clean way to access form options in event listener

Viewed 3113

How can I access $options passed to buildForm() from an event listener in a clean way? Please see below code sample:

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->addEventListener(FormEvents::PRE_SET_DATA, [$this, 'preSetDataListener']);
    }

    public function preSetDataListener(FormEvent $event)
    {
        // how would I access $options from buildFrom here?
    }
4 Answers

Don't rely on $event->getForm()->getConfig()->getOptions(). It's not meant to be used by us. I've opened an issue on the Symfony bug tracker with this problem and they told me to inherit variables into the anonymous function instead. See this example.

Pay attention to the use keyword.

->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options) {
    // here you can use $options
}

That gets the $options array from the parent scope and injects it into the event listener function. It's a PHP feature.

Oh, and this means you'll have to either directly pass an anonymous function as an argument to addEventListener() (as in the example above) or define it inside buildForm() as a normal variable, like this:

$listener = function (FormEvent $event) use ($options) {
    // do something
}

$builder
    ->addEventListener(FormEvents::PRE_SET_DATA, $listener);

It's often handy to get them selected one instead of full array:

$event->getForm()->getConfig()->getOption('option_key')

If you need the full array however, go with Artur's suggestion:

$event->getForm()->getConfig()->getOptions()
Related