Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Upgrading to Symfony 3!

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $5.00

We are now finally ready to upgrade our project to Symfony 3. How do we do that? It's a simple, 2 step process.

First, in composer.json change the symfony/symfony key, to 3.0.*:

66 lines composer.json
... lines 2 - 12
"require": {
... lines 14 - 30
"symfony/symfony" : "3.0.*",
... line 32
... lines 34 - 64

Or, if you're upgrading to any even new version, use that - like 3.1.*.

Second, run composer update. This time, run it with no arguments:

composer update

We technically only need to upgrade the symfony/symfony package, but since so many libraries depend on this, it's pretty tough to only update Symfony. If you're worried about too much stuff upgrading, make sure you version constraints in composer.json are really tight.

But as we wait for this: I have a surprise! This will almost definitely not work.

Upgrading other Libraries

And just as I say that, huge error! Oh boy, these are a pain to read at first. But if you follow down, eventually you'll find the problem. Ah, there it is: the installation for sensio/distribution-bundle requires symfony/process at version 2.2. In normal English, Composer is saying:

Yo! Your version of sensio/distribution-bundle in composer.json needs symfony/process 2.2. You probably need to upgrade the distribution bundle to a new version that works with symfony/process version 3.

This means we need to update the version for sensio/distribution-bundle in composer.json to something higher. In these cases, I like to open Packagist and search for symfony/framework-standard-edition. This is the project you get when you first download Symfony. We can cheat by looking at its composer.json versions.

Let's see what it looks like at the latest 3.0 version - 3.0.8. Ok - this project requires sensio/distribution-bundle at version ^5.0. Open our composer.json and change it to match: ^5.0:

66 lines composer.json
... lines 2 - 12
"require": {
... lines 14 - 25
"sensio/distribution-bundle" : "^5.0",
... lines 27 - 32
... lines 34 - 64

That's it! Run Composer update again:

composer update

We may get another error about another library, but this is the process: run $ composer update, find the problematic package, update its version and repeat.

Yep: another problem. This time it's from sensio/generator-bundle. Go back to Packagist: the version in the Standard Edition is ^3.0. Update our composer.json:

66 lines composer.json
... lines 2 - 33
"require-dev": {
"sensio/generator-bundle": "^3.0"
... lines 37 - 64

And run Composer again:

composer update

If you get an error from a package that's not part of the Standard Edition, then you'll need to go look up that library in Packagist or on GitHub to find a version that's 3.0-compatible. That's exactly what we did with AsseticBundle.

Et voila! We just downloaded Symfony 3.0.8.

Well, let's see if it works! Refresh! Yes! Everything looks great: a major framework upgrade without breaking your code! Give yourself a congrats. And then, don't forget to run your tests and QA your site to make sure we didn't missing anything.

All right, guys, if you have any questions, let me know.

Seeya next time!

Leave a comment!

Login or Register to join the conversation
Default user avatar

One question: could we do this on easier way? for example:
1) install sf 3 (new folder)
2) copy src (sf 2.7) folder to new symfony 3 (maybe cache and logs files if we want)
3) fix only our code
4) if works fine, move to prod server
On this way we can avoid symfony core and external bundles upgrade issues and focus only on our code (AppBundle).
Is this good idea :) ?


Hey axa,

Actually, I think your idea is partially OK, but it depends, because if we talk about real project - you will have a lot of custom configuration and dependencies. For example, except src/ folder you may have your own dependencies in composer.json, a lot of custom configuration in app/config/*.yml files, etc, so just copying src/ folder does not enough. And probably the most important problem is that this way you lose all your Git history, i.e. you create a new project where you'll need to do "git init" which means you start with empty Git repo. Also, most probably cache and logs from the previous project won't work, so copying them is pointless.

And btw, do not forget to run your tests before pushing to production (you write tests, right?) :)

Anyway, your way looks more time consuming as for me.


Default user avatar

Yes, you are right... Thanks for answer.

Default user avatar

After upgrading to symfony 3.0 I'm unable to get pass this error:
Invalid key "container" found in arguments of method "__construct()" for service "mailchimp": only integer or $named arguments are allowed.
Is it related to : [BC BREAK] non-numeric keys in methods and constructors arguments have never been supported and are now forbidden. Please remove them if you happen to have one.

The problem I'm having is locating where this error is happening to solve it.
Any help would be appreciated, thank you


Hey claire

Can you post your services.yml file? Look like you/or something is injecting the container into the mailchimp service in a deprecated way


Default user avatar
Default user avatar claire | MolloKhan | posted 5 years ago | edited

It pretty big so here the snippets which are using mailchimp. But if it helps i can post the whole thing.

        class: Line\FringeBundle\Email\MailchimpManager
        arguments: [ '@mailchimp', '@line_fringe.setting_manager' ]
        lazy: true

        class: Line\FringeBundle\Entity\Manager\UserManager
        arguments: [ '@doctrine.orm.entity_manager', '@security.encoder_factory', '@line_via.line_via_api', '@line_fringe.mailchimp_manager', '@line_fringe.mailer', '@line_fringe.setting_manager']

Thank you for taking the time to help me MolloKhan :)


Yo claire!

Yes, so I do know this error. Let me explain it first (actually it looks like you found the [BC BREAK] item), and then we'll see if we can find the cause! Normally (as you do in your code) when you pass arguments to a service, it looks like this (your example above passes the arguments all on 1 line, but it's equivalent to this multi-line version)

        - foo
        - bar

But, in Symfony 2, it was legal to do this instead:

        something: foo
        somethingelse: bar

In this case, you're naming the keys to your arguments. This had absolutely no effect - the above to examples created identical services. In Symfony 3, we made using string keys like this illegal (we did this because we now allow named arguments https://knpuniversity.com/screencast/symfony-3.3/named-arguments).

So, somewhere in your code, someone is doing this - and using a "container" key. And the problem is indeed in the bundle: https://github.com/AlmogBaku/MailchimpBundle/blob/master/Resources/config/services.yml#L5

I think you need to find a new bundle :). A quick search reveals this one: https://github.com/AhmedSamy/HypeMailchimpBundle, though I have never used it. But honestly, the bundle you're using isn't giving you anything, besides that one service definition - https://github.com/AlmogBaku/MailchimpBundle/blob/master/Resources/config/services.yml#L5 and this one class: https://github.com/AlmogBaku/MailchimpBundle/blob/master/Mailchimp/Mailchimp.php. You could just copy those into your code very easily :).

I hope that helps!

Default user avatar

Had a thought could it be to do with the 'godisco/mailchimp-bundle' , im on the latest version but it seems it not been updated in a while. Looking into this bundles dependency injection I see :

public function load(array $configs, ContainerBuilder $container)
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);

$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));

$container->setParameter("mailchimp.api_key", $config['api_key']);
$container->setParameter("mailchimp.default_list", $config['default_list']);

Could this be the cause? If so , what would you recommend, maybe finding a replacement bundle?

Cat in space

"Houston: no signs of life"
Start the conversation!

What PHP libraries does this tutorial use?

// composer.json
    "require": {
        "php": ">=5.3.9",
        "ext-pdo_sqlite": "*",
        "doctrine/doctrine-bundle": "~1.5", // 1.6.3
        "doctrine/doctrine-fixtures-bundle": "~2.2", // 2.3.0
        "doctrine/orm": "~2.4", // v2.5.4
        "erusev/parsedown": "~1.5", // 1.6.0
        "ezyang/htmlpurifier": "~4.7", // v4.7.0
        "incenteev/composer-parameter-handler": "~2.1", // v2.1.2
        "ircmaxell/password-compat": "~1.0", // v1.0.4
        "knplabs/knp-paginator-bundle": "~2.4", // 2.5.3
        "leafo/scssphp": "~0.1.5", // v0.1.10
        "patchwork/jsqueeze": "~1.0", // v1.0.7
        "sensio/distribution-bundle": "^5.0", // v5.0.7
        "sensio/framework-extra-bundle": "~3.0", // v3.0.16
        "symfony/assetic-bundle": "~2.8", // v2.8.0
        "symfony/monolog-bundle": "~2.7", // 2.11.1
        "symfony/swiftmailer-bundle": "~2.3", // v2.3.11
        "symfony/symfony": "3.0.*", // v3.0.9
        "twig/extensions": "~1.2" // v1.3.0
    "require-dev": {
        "sensio/generator-bundle": "^3.0" // v3.0.7