Important Tips That You Need To Know Before Upgrade Your Project From Symfony 2 To Symfony 3

In this article we will share with you the most significant changes for your code in the new version. We suggest you too a couple of tips before proceed with your upgrade :
  • Check that your server supports at least PHP 5.5.9
  • Make your code deprecation free (using phpunit or pay attention to the symfony dev profiler).
  • Check that all the bundles that you use supports symfony 3 already, otherwise don't upgrade.
  • Time ! As this update can cause problems with your actual code and you may need time to solve them.

The getRequest method of the base Controller class has been deprecated since Symfony 2.4 and must be therefore removed in 3.0. The only reliable way to get the Request object is to inject it in the action method.

That means that we will not get the request inside the action, instead we'll receive the request as parameter in the function.

namespace myBundleController;use SymfonyComponentHttpFoundationRequest;class StartController{   public function showAction(Request $request)   {       // $request->query->get('aGetParameter')   }}

The form.csrf_provider service is removed as it implements an adapter for the new token manager to the deprecated SymfonyComponentFormExtensionCsrfCsrfProviderCsrfProviderInterface interface. The security.csrf.token_manager should be used instead.

The intention firewall listener setting was renamed to csrf_token_id. 

The csrf_provider firewall listener setting was renamed to csrf_token_generator.

# Using FOSUserBundle for examplemain:    pattern: ^/    form_login:        provider: fos_userbundle        csrf_token_generator: security.csrf.token_manager        # in Symfony < 2.8, we used instead :        # csrf_provider: form.csrf_provider

Some route settings has been renamed and will not work anymore in symfony 3 :

  • The pattern setting has been removed in favor of path
  • The _scheme and _method requirements have been moved to the schemes and methods settings
# Deprecatedarticle_edit: pattern: /article/{id} requirements: { '_method': 'POST|PUT', '_scheme': 'https', 'id': 'd+' }# Nowarticle_edit: path: /article/{id} methods: [POST, PUT] schemes: https requirements: { 'id': 'd+' }

Although you may think this is not so relevant, if you create your own services, this may be useful.

  • Using a colon in an unquoted mapping value leads to a ParseException.
  • Starting an unquoted string with @, , |, or > leads to a ParseException. 
  • When surrounding strings with double-quotes, you must now escape characters. Not escaping those characters (when surrounded by double-quotes) leads to a ParseException.
# this will lead to a ParseExceptionclass: "FooVar"# escape the characters or simply do not encapsulate a class in quotesclass: "Foo\Var"class: FooVar

Type names were removed. Instead of referencing types by name, you must reference them by their fully-qualified class name (FQCN) instead.

We use to give the type as second parameter in the form builder:

$form = $this->createFormBuilder()->add('name', 'text')->add('age', 'integer')->getForm();

however now we can't give the name as a string !

use SymfonyComponentFormExtensionCoreTypeIntegerType;use SymfonyComponentFormExtensionCoreTypeTextType;use SymfonyComponentFormExtensionCoreTypeTextareaType;use SymfonyComponentFormExtensionCoreTypeDateType;use SymfonyComponentFormExtensionCoreTypeDatetimeType;// Don't forget to include the typeClass$form = $this->createFormBuilder()->add('name', TextType::class) ->add('age', IntegerType::class)->add('description', TextareaType::class)->getForm();

On the types, we found for example : SubmitType, UrlType, FormType, HiddenType, LocaleType etc .. (See SymfonyComponentFormExtensionCoreType folder for more types)

Passing type instances to Form::add(), FormBuilder::add() and the FormFactory::create*() methods is not supported anymore. Pass the fully-qualified class name of the type instead.

In the controllers we used to create a new instance of the type of your entity :

use thisismyBundleFormMyCustomType;$form = $this->createForm(new MyCustomType(),$entity .......);

Now we'll use instead :

use thisismyBundleFormMyCustomType;$form = $this->createForm(MyCustomType::class,$entity .......);

Passing a SymfonyComponentHttpFoundationRequest instance, as was supported by FormInterface::bind(), is not possible with FormInterface::submit() anymore. You should use FormInterface::handleRequest() instead.

If your Symfony version >= 2.6.* you will not face this issue. The bind method has been removed, you need to use handleRequest instead. Old way :

if ('POST' === $request->getMethod()) { $form->bind($request); if ($form->isValid()) { // do some stuff }}

Now we'll handle the request directly:

$form->handleRequest($request);if ($form->isValid()) { // do some stuff and redirect}



If you want to know more details or this post doesn't fit with your need, read the complete upgrade list in the symfony repository here. Have fun and may the force be with you on this journey.

  • 90