symfony/symfony — pull request #12255 by cleentfaar (2014-10-19 00:16:48+00:00)
Title: [OptionsResolver] Require arrays to be of a certain type

| Q | A
| ------------- | ---
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | symfony/symfony-docs#4339

## What does it do?
This PR allows users to define their options to be **arrays of a certain type**, as documented [on phpdoc](http://phpdoc.org/docs/latest/guides/types.html).

For example, using `stdClass[]`:
```php
$resolver->setAllowedTypes(array(
'foo' => 'stdClass[]'
));
```
...would ensure the value of `foo` to be an array of `stdClass`-instances.

I've also added supported for the alternate way of writing this, which is `array`:
```php
$resolver->setAllowedTypes(array(
'foo' => 'array'
));
```
...and has the same effect.

To make things even easier (at least for my own use-cases), I've also added a very neat feature where you can even define the array's keys to be of a certain type:
```php
$resolver->setAllowedTypes(array(
'foo' => 'array'
));
```
...which would force an array to have keys of type `string` and values of type `integer`.

## Why? Can't you just use callbacks?
I've been using a lot of callbacks in my resolver-configurations *just* to make sure my arrays contain instances of the correct class, and this has made it quite unreadable to say the least. I could fall back to using my own libraries but I think this could suit others as well.
Practically, having this feature would allow me to shorten my configuration in most of my code down to about a third of what it is now, just removing all the callbacks I won't be needing.
Additionally, I think users who have similar set-ups (requiring arrays to have certain types of values) will also profit from this.

## Performance
I've been made aware in previous PR's that the OptionsResolver-component has to be very light as it is accessed so many times by the symfony framework during a request-cycle. Because of this, I've tried my best to keep give this feature the lowest priority in the checks during `validateTypes`. This is also why I've added the `is_array` check before calling `validateNestedType` (just to safe a few more calls). It is also why I decided to simply copy the type-checking code (`is_{$type}()`, `$type instanceof`, etc...), instead of moving all of it to a separate method (being the DRY-fan I am), but at the same time forcing a call to it on every `$type`-iteration in the `validateTypes()`-method (calling other methods was the real killer I believe?).
I am not sure if my way of avoiding this is sufficient... or perhaps even overkill (I hope the latter :smile:). For what it's worth though, I'd give this PR very little priority over others, perhaps even pending it for 3.x?

## Attributions
The formats for writing the types are inspired by @schmittjoh's [Serializer](https://github.com/schmittjoh/serializer) package, which allows you to indicate array values in the same way.

The definition of the similar phpdoc format can be found [here](http://phpdoc.org/docs/latest/guides/types.html).