Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Upgrading to Symfony 5.0

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 $10.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

We've done it! We fixed all the deprecations in our app... except for the doctrine/persistence stuff, which we don't need to worry about because we're not upgrading that library. That means... we are ready for Symfony5!

Changing composer.json for Symfony 5.0

How... do we actually upgrade? We already know: it's the exact same process we used to upgrade from 4.3 to 4.4.

Open up composer.json. Our goal is to update all of these symfony/ libraries to 5.0:

105 lines composer.json
{
... lines 2 - 3
"require": {
... lines 5 - 24
"symfony/asset": "4.4.*",
"symfony/console": "4.4.*",
"symfony/dotenv": "4.4.*",
"symfony/flex": "^1.0",
"symfony/form": "4.4.*",
"symfony/framework-bundle": "4.4.*",
"symfony/mailer": "4.4.*",
"symfony/messenger": "4.4.*",
"symfony/monolog-bundle": "^3.5",
"symfony/security-bundle": "4.4.*",
"symfony/sendgrid-mailer": "4.4.*",
"symfony/serializer-pack": "^1.0",
"symfony/twig-bundle": "4.4.*",
"symfony/twig-pack": "^1.0",
"symfony/validator": "4.4.*",
"symfony/webpack-encore-bundle": "^1.4",
"symfony/yaml": "4.4.*",
... lines 42 - 44
},
"require-dev": {
... lines 47 - 48
"symfony/browser-kit": "4.4.*",
"symfony/debug-bundle": "4.4.*",
"symfony/maker-bundle": "^1.0",
"symfony/phpunit-bridge": "4.4.*",
"symfony/profiler-pack": "^1.0",
"symfony/var-dumper": "4.4.*"
},
... lines 56 - 103
}

Well, not quite all of them - a few are not part of the main Symfony library, like monolog-bundle. But basically, everything that has 4.4.* now needs to be 5.0.*.

We also need to update one more thing: the extra.symfony.require value:

105 lines composer.json
{
... lines 2 - 96
"extra": {
"symfony": {
... lines 99 - 100
"require": "4.4.*"
}
}
}

This is primarily a performance optimization that helps Composer filter out extra Symfony versions when it's trying to resolve packages. This also needs to change to 5.0.*.

Let's... do it all at once: Find 4.4.*, replace it with 5.0.* and hit "Replace all":

105 lines composer.json
{
... lines 2 - 3
"require": {
... lines 5 - 24
"symfony/asset": "5.0.*",
"symfony/console": "5.0.*",
"symfony/dotenv": "5.0.*",
... line 28
"symfony/form": "5.0.*",
"symfony/framework-bundle": "5.0.*",
"symfony/mailer": "5.0.*",
"symfony/messenger": "5.0.*",
... line 33
"symfony/security-bundle": "5.0.*",
"symfony/sendgrid-mailer": "5.0.*",
... line 36
"symfony/twig-bundle": "5.0.*",
... line 38
"symfony/validator": "5.0.*",
... line 40
"symfony/yaml": "5.0.*",
... lines 42 - 44
},
"require-dev": {
... lines 47 - 48
"symfony/browser-kit": "5.0.*",
"symfony/debug-bundle": "5.0.*",
... line 51
"symfony/phpunit-bridge": "5.0.*",
... line 53
"symfony/var-dumper": "5.0.*"
},
... lines 56 - 96
"extra": {
"symfony": {
... lines 99 - 100
"require": "5.0.*"
}
}
}

And then... make sure that this didn't accidentally replace any non-Symfony packages that may have had the same version.... looks good.

Updating Symfony Packages in Composer

We're ready! At your terminal... I'll hit Ctrl+C to stop the log tail.... and run the same command we used when upgrading from Symfony 4.3 to 4.4:

composer update "symfony/*"

That's it! It's that easy! We're done! Kidding - it's never that easy: you will almost definitely get some dependency errors. Probably... several. Ah, here's our first.

Composer: Many Packages Need to Update

These errors are always a little hard to read. This says that the current version of doctrine/orm in our project is not compatible with Symfony 5... which means that it also needs to be updated. Specifically we need a newer version that's compatible with symfony/console version 5.

And... it's possible that there is not yet a release of doctrine/orm that supports Symfony 5 - we hit that problem earlier with StofDoctrineExtensionsBundle. But... let's blindly try it! Add doctrine/orm to our update list and try again:

composer update "symfony/*" doctrine/orm

And... another error. Actually, the same error but this time for knplabs/knp-markdown-bundle. We don't know if this bundle has a Symfony5-compatible release either... and even if it does... it might require a major version upgrade. But the easiest thing to do is add it to our list and hope for the best. Try it:

composer update "symfony/*" doctrine/orm knplabs/knp-markdown-bundle

So... this is going to happen several more times - this is the same error for knplabs/knp-snappy-bundle. Little-by-little, we're discovering all the packages that we need to upgrade to be compatible with Symfony 5. Instead of doing this one-by-one, you can also choose the easy route: just run composer update with no arguments and allow Composer to update everything.

I prefer to upgrade more cautiously than that... but it's not a bad option. After all, our Composer version constraints don't allow any major version upgrades: so running composer update still won't allow any new major package versions unless you tweaked your composer.json file.

Let's keep going with my cowardly, I mean, cautious way: copy the package name and add it to the update command:

composer update "symfony/*" \
                doctrine/orm \
                knplabs/knp-markdown-bundle \
                knplabs/knp-snappy-bundle

Let's keep trying and... I'll fast-forward through a few more of these: this is for liip/imagine-bundle - add that to the update command - then oneup/flysystem-bundle... and now sensio/framework-extra-bundle: add that to our very-long update command:

composer update "symfony/*" \
                doctrine/orm \
                knplabs/knp-markdown-bundle \
                knplabs/knp-snappy-bundle \
                liip/imagine-bundle \
                oneup/flysystem-bundle \
                sensio/framework-extra-bundle

Updating --with-dependencies

Hmm, but this next error looks a bit different: it's something about doctrine/orm and doctrine/instantiator. If you look closely, this says that in order to get Symfony 5 support, we need doctrine/orm version 2.7, but version 2.7 requires doctrine/instantiator 1.3... and our project is currently locked at version 1.2.

Our app doesn't require doctrine/instantiator directly: it's a dependency of doctrine/orm. We saw this earlier when we were updating doctrine-migrations-bundle and we also needed to allow its dependency - doctrine/migrations to update.

We allow that by adding --with-dependencies to the update command:

composer update "symfony/*" \
                doctrine/orm \
                knplabs/knp-markdown-bundle \
                knplabs/knp-snappy-bundle \
                liip/imagine-bundle \
                oneup/flysystem-bundle \
                sensio/framework-extra-bundle \
                --with-dependencies

Updating our PHP Version

And... this gets us to our next error. Oh, interesting! Apparently nexylan/slack-bundle version 2.2.1 requires PHP 7.3! We saw a similar error earlier, which caused us to decide that our production app would now need to at least run PHP 7.2. We enforced that by adding a config.platform.php setting in composer.json to 7.2.5. This says:

Yo Composer! Pretend I'm using PHP 7.2.5 and don't let me use any packages that require a higher version of PHP.

So... hmm. Apparently the version of nexylan/slack-bundle that supports Symfony 5 requires PHP 7.3. Basically... unless we want to stop using that bundle, it means that we need to start using PHP 7.3 as well.

Fortunately, I'm already using PHP 7.3 locally: so I just need to change my config.platform.php setting to 7.3 and also makes sure that we have 7.3 on production.

Inside composer.json, search for platform: there it is. Use 7.3.0. And, even though it doesn't affect anything in a project, also change the version under the require key:

105 lines composer.json
{
... lines 2 - 3
"require": {
"php": "^7.3.0",
... lines 6 - 44
},
... lines 46 - 55
"config": {
... lines 57 - 60
"platform": {
"php": "7.3.0"
}
},
... lines 65 - 103
}

Ok, now try to update:

composer update "symfony/*" \
                doctrine/orm \
                knplabs/knp-markdown-bundle \
                knplabs/knp-snappy-bundle \
                liip/imagine-bundle \
                oneup/flysystem-bundle \
                sensio/framework-extra-bundle \
                --with-dependencies

Bah! I should've seen that coming: it's still complaining about nexylan/slack-bundle: it's reminding us that we need to also allow that bundle to update. Add it to our list:

composer update "symfony/*" \
                doctrine/orm \
                knplabs/knp-markdown-bundle \
                knplabs/knp-snappy-bundle \
                liip/imagine-bundle \
                oneup/flysystem-bundle \
                sensio/framework-extra-bundle \
                nexylan/slack-bundle \
                --with-dependencies

And try it. Surprise! Another package needs to be update. I swear we're almost done. Add that to our gigantic update command:

Tip

We need this for our course CI, just ignore this note and follow the tutorial without executing these commands :)

sed -i 's/"4.4.*"/"5.0.*"/g' ./composer.json
sed -i 's/public function getExtendedType()/public static function getExtendedTypes(): iterable/g' ./src/Form/TypeExtension/TextareaSizeExtension.php
sed -i 's/TextareaType::class/\[TextareaType::class\]/g' ./src/Form/TypeExtension/TextareaSizeExtension.php
sed -i 's/extends Controller/extends AbstractController/g' ./src/Controller/CommentAdminController.php
sed -i 's/use Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller/use Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController/g' ./src/Controller/CommentAdminController.php
sed -i 's/use Doctrine\\Common\\Persistence\\ObjectManager/use Doctrine\\Persistence\\ObjectManager/g' ./src/DataFixtures/ArticleFixtures.php
sed -i 's/use Doctrine\\Common\\Persistence\\ObjectManager/use Doctrine\\Persistence\\ObjectManager/g' ./src/DataFixtures/BaseFixture.php
sed -i 's/use Doctrine\\Common\\Persistence\\ObjectManager/use Doctrine\\Persistence\\ObjectManager/g' ./src/DataFixtures/CommentFixture.php
sed -i 's/use Doctrine\\Common\\Persistence\\ObjectManager/use Doctrine\\Persistence\\ObjectManager/g' ./src/DataFixtures/TagFixture.php
sed -i 's/use Doctrine\\Common\\Persistence\\ObjectManager/use Doctrine\\Persistence\\ObjectManager/g' ./src/DataFixtures/UserFixture.php
echo "delete duplicated file" && rm config/routes/dev/twig.yaml
composer update "symfony/*" \
                doctrine/orm \
                knplabs/knp-markdown-bundle \
                knplabs/knp-snappy-bundle \
                liip/imagine-bundle \
                oneup/flysystem-bundle \
                sensio/framework-extra-bundle \
                nexylan/slack-bundle \
                knplabs/knp-time-bundle \
                easycorp/easy-log-handler \
                knplabs/knp-paginator-bundle \
                stof/doctrine-extensions-bundle \
                doctrine/doctrine-bundle \
                doctrine/doctrine-fixtures-bundle \
                doctrine/doctrine-migrations-bundle \
                twig/cssinliner-extra \
                --with-dependencies

Other than Symfony: (Mostly) Only Safe Minor Upgrades

And... whaaaat? It's working! It's upgrading a ton of packages, including the Symfony stuff to 5.0.2. And, because we didn't change any other version constraints inside composer.json, we know that all of these upgrades are just minor version upgrades at best. For example, nexylan/slack-bundle went from 2.1 to 2.2. Even if there were a new version 3 of this bundle, we know that it wouldn't upgrade to it because its version constraint is ^2.1, which allows 2.1 or higher, but not 3:

105 lines composer.json
{
... lines 2 - 3
"require": {
... lines 5 - 20
"nexylan/slack-bundle": "^2.1",
... lines 22 - 44
},
... lines 46 - 103
}

Well, that's not completely true: check out nexylan/slack: it went from version 2.3 to 3: that is a major upgrade. That's because this is one of those transitive dependencies: this package isn't in our composer.json, it only lives in our project because nexylan/slack-bundle requires it. So unless we're using its code directly - which is possible, but less likely - the major upgrade won't affect us. If you're worried, check its CHANGELOG.

Ok, so we are now on Symfony 5. Woo! The little icon on the bottom right of the web debug toolbar shows 5.0.2.

Next, let's celebrate by trying out some new features! We'll start by talking about Symfony's new "secrets management".

Leave a comment!

13
Login or Register to join the conversation
Boubacar S. Avatar
Boubacar S. Avatar Boubacar S. | posted 3 years ago

Hi. After upgrating to symfony 5, but when acccessing to an article details (/news/{slug}), i have the following error :
"No PSR-17 request factory found. Install a package from this list: https://packagist.org/provi...."

I tried to install some PSR-17 implementations from packagist but didn't fix it.

If i remove SlackClient $slack param from the show method, the error desapear.

How can i fix it without removing the SlackClient $slack param..

Thank you in advance.

1 Reply

Hey Boubacar S.

I don't really know why it asks for a "request factory" but if you install the package "nyholm/psr7" it should work. If it doesn't, please let us know

Cheers!

1 Reply
Boubacar S. Avatar

Thank you . After installing "nyholm/psr7" it works perfectly .

Reply

Hey Boubacar S.!

Awesome! Thanks for letting us know. We talk a bit more about this in the last chapter - https://symfonycasts.com/sc... - basically one of our "transitive dependencies" (nexylan/slack) gets bumped up a major version (from 2 to 3) and this has some BC breaks (specifically, that you need an external library for it to work).

Cheers!

Reply
MattWelander Avatar
MattWelander Avatar MattWelander | posted 1 year ago

I can't use the symfony/* syntax, it tells me

mattias@acr-se-003-hk webtools % composer update symfony/*
zsh: no matches found: symfony/*

I can follow along just fine with running the whole composer update, just curious why it doesn't work for me when it works for you =)

Reply

Hey Mattias,

Ah, yes, this command may cause an error in ZSH, it's because of that * char, but you just need to wrap that string with quotes - easy fix ;) In short, just try this command instead:

$ composer update "symfony/*"

P.S. Btw notice that we have those quotes in the scripts ;)

Cheers!

Reply
odds Avatar

So, I'm in the process of upgrading a Symfony 4.4 and wondering if I should upgrade to 5.0 first, than to 5.1, to 5.2, to 5.3 and finally 5.4 or just upgrade to 5.4 at once?

Reply
sadikoff Avatar sadikoff | SFCASTS | odds | posted 1 year ago | edited

hey odds

If you don't have any deprecated errors, then it will be good to upgrade 4.4 -> 5.4

Cheers!

Reply
Dmitriy Avatar
Dmitriy Avatar Dmitriy | posted 3 years ago

Hi. I am trying to update Symfony to 5 version and have error:

zenstruck/redirect-bundle v3.3.1 requires symfony/framework-bundle ^2.8|^3.0|^4.0 -> satisfiable by symfony/framework-bundle[v4.4.2] but these conflict with your requirements or minimum-stability

zenstruck/redirect-bundle has no support yet Symfony 5.

How can I skip updating this package and continue updating Symfony without it?

Reply

Hey Dmitriy

No you can't skip it, you can wait for support(better will be to ping author or make a PR to add support) or find another library which support Symfony 5

Cheers!

Reply
Francisco C. Avatar
Francisco C. Avatar Francisco C. | posted 3 years ago

Hi Ryan (andeverybody)

I have a problem with upgrading a third bundle BackupManager in Symfony5

https://github.com/backup-m...

In its changelog file it seems to have support for Symfony5.0 in its version 2.3.0. When I run

composer require backup-manager/symfony

I get this message:

Problem 1
- backup-manager/backup-manager 1.4.1 requires symfony/process ^2.1 || ^3.0 || ^4 -> no matching package found.
- backup-manager/backup-manager 1.4 requires symfony/process ^2.1 || ^3.0 || ^4.0 -> no matching package found.
- backup-manager/backup-manager 1.3.0 requires symfony/process ^2.1 || ^3.0 || ^4.0 -> no matching package found.
- backup-manager/symfony 2.3.0 requires backup-manager/backup-manager ^1.3 -> satisfiable by backup-manager/backup-manager[1.3.0, 1.4, 1.4.1].
- Installation request for backup-manager/symfony ^2.3 -> satisfiable by backup-manager/symfony[2.3.0].

But I have installed (updated) symfony/process in version 5.0.*. I have created an issue in author's bundle github page but ... Anyone does it has any idea? Where can it be the problem?

Thanks
Francisco

Reply

Hi Francisco C.

If you try to dig this error you can find that backup-manager/backup-manager requires symfony/process ^2.1 || ^3.0 || ^4 so it cannot be installed in you project. So need to wait while backup-manager/backup-manager will be updated

Cheers!

Reply
Francisco C. Avatar
Francisco C. Avatar Francisco C. | sadikoff | posted 3 years ago

I thought what its release 2.3.0 named Symfony5 support covered this. I will hope then. Thanks

Reply
Cat in space

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

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": "^7.3.0",
        "ext-iconv": "*",
        "antishov/doctrine-extensions-bundle": "^1.4", // v1.4.2
        "aws/aws-sdk-php": "^3.87", // 3.110.11
        "composer/package-versions-deprecated": "^1.11", // 1.11.99
        "doctrine/doctrine-bundle": "^2.0", // 2.0.6
        "doctrine/doctrine-migrations-bundle": "^1.3|^2.0", // 2.1.2
        "doctrine/orm": "^2.5.11", // v2.7.2
        "doctrine/persistence": "^1.3.7", // 1.3.8
        "easycorp/easy-log-handler": "^1.0", // v1.0.9
        "http-interop/http-factory-guzzle": "^1.0", // 1.0.0
        "knplabs/knp-markdown-bundle": "^1.7", // 1.8.1
        "knplabs/knp-paginator-bundle": "^5.0", // v5.0.0
        "knplabs/knp-snappy-bundle": "^1.6", // v1.7.0
        "knplabs/knp-time-bundle": "^1.8", // v1.11.0
        "league/flysystem-aws-s3-v3": "^1.0", // 1.0.23
        "league/flysystem-cached-adapter": "^1.0", // 1.0.9
        "league/html-to-markdown": "^4.8", // 4.8.2
        "liip/imagine-bundle": "^2.1", // 2.3.0
        "nexylan/slack-bundle": "^2.1", // v2.2.1
        "oneup/flysystem-bundle": "^3.0", // 3.3.0
        "php-http/guzzle6-adapter": "^2.0", // v2.0.1
        "sensio/framework-extra-bundle": "^5.1", // v5.5.3
        "symfony/asset": "5.0.*", // v5.0.2
        "symfony/console": "5.0.*", // v5.0.2
        "symfony/dotenv": "5.0.*", // v5.0.2
        "symfony/flex": "^1.0", // v1.17.6
        "symfony/form": "5.0.*", // v5.0.2
        "symfony/framework-bundle": "5.0.*", // v5.0.2
        "symfony/mailer": "5.0.*", // v5.0.2
        "symfony/messenger": "5.0.*", // v5.0.2
        "symfony/monolog-bundle": "^3.5", // v3.5.0
        "symfony/security-bundle": "5.0.*", // v5.0.2
        "symfony/sendgrid-mailer": "5.0.*", // v5.0.2
        "symfony/serializer-pack": "^1.0", // v1.0.2
        "symfony/twig-bundle": "5.0.*", // v5.0.2
        "symfony/twig-pack": "^1.0", // v1.0.0
        "symfony/validator": "5.0.*", // v5.0.2
        "symfony/webpack-encore-bundle": "^1.4", // v1.7.2
        "symfony/yaml": "5.0.*", // v5.0.2
        "twig/cssinliner-extra": "^2.12", // v2.12.0
        "twig/extensions": "^1.5", // v1.5.4
        "twig/inky-extra": "^2.12" // v2.12.0
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.0", // 3.3.0
        "fzaninotto/faker": "^1.7", // v1.8.0
        "symfony/browser-kit": "5.0.*", // v5.0.2
        "symfony/debug-bundle": "5.0.*", // v5.0.2
        "symfony/maker-bundle": "^1.0", // v1.14.3
        "symfony/phpunit-bridge": "5.0.*", // v5.0.2
        "symfony/profiler-pack": "^1.0", // v1.0.4
        "symfony/var-dumper": "5.0.*" // v5.0.2
    }
}
userVoice