Symfony 2 expects a perfectly configured server environment. This sadly isn’t always true, because a lot of legacy code is still running on those machines. Therefore you can’t just reconfigure it.

This makes programming good and fault-proof applications much more difficult. But Symfony wouldn’t be a great framework if it hadn’t prepared for such occasion.

In our example the user enters a float number with a comma instead of a (database friendly) point as decimal separator in an input field.
I.e.: “100,32”. By default symfony removes the “,” according to the servers locale, which would be alright if the server is configured to use the German locale “Europe\Berlin”.

But if you have to use a non-german config the expected format is “100.32” and symfony removes the obsolete comma which results in a far too high number: “10032”.

To avoid this, we can attach data transformers to form fields, which - like the name already gives away - transforms data to and from a form field.
This is especially convenient for quite sophisticated transformations like converting entities to input values etc., which normally are cramped into controller actions.

The data transformer can look something like this:

<?php
namespace Scandio\PlaygroundBundle\DataTransformer;
use Symfony\Component\Form\DataTransformerInterface;
class FloatTransformer implements DataTransformerInterface
{
    /**
     * Transforms from DB value to form value
     * @param mixed $value
     * @return string
     */
    public function transform($value)
    {
        return number_format($value, 2, ',', '');
    }
    /**
	 * Reverse transforms form value to db value
     * @param mixed $value
     * @return float
     */
    public function reverseTransform($value)
    {
        return (float) str_replace(',', '.', $value);
    }
}

This basic float number transformer takes a float value and uses a comma as decimal separator. In the form (input field) it will look like this: “56432,10”.
After submitting the form, the value is transformed back to “56432.1” as a float number. This garanties us, that the number stored in the database is always a float number without the unwanted side effects.

To activate it, it gets a bit tricky. Symfony uses the float locale normalizer by default to transform float input fields. This would be alright if the server is correctly configured.
We first have to remove all default transformers from the form field and then attach the FloatTransformer to the form field. This guarantees us that no other data transformer interferes with the float number beforehand.

In the form type it could look something like this:

<?php
namespace Scandio\PlaygroundBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Doctrine\ORM\EntityRepository;
use Scandio\PlaygroundBundle\DataTransformer\FloatTransformer;
class PriceType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
            ->add('date')
            ->add(
                $builder->create('price')
                    ->resetClientTransformers()
                    ->prependNormTransformer(new FloatTransformer())
            )
        ;
    }
    public function getName()
    {
        return 'scandio_playgroundbundle_price';
    }
}

The “price” form field should now use the FloatTransformer by default.
First we reset all ClientTransformers, which removes all default symfony2 framework data transformers. Then we prepend our FloatTransformer.

That’s it. Now the user can enter float numbers with “,” as decimal separator and you as a developer don’t have to worry about false float values.

For more examples you can always head over to the official symfony2 documentation: How to use Data Transformers.