Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Upgrading to Symfony 6.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

Finally, it's time to upgrade to Symfony 6! Woo!

Rector Upgrades to 6.0

But first, just in case, let's run Rector one more time. Go back to Rector's repository, click the Symfony link, and... steal the same code that we had earlier. Paste that into our rector.php file. Then, just like we did for Symfony 5.4, change SymfonySetList to SymfonyLevelSetList, and this time, say UP_TO_SYMFONY_60.

28 lines rector.php
... lines 1 - 14
return static function (ContainerConfigurator $containerConfigurator): void {
... lines 16 - 23
$containerConfigurator->import(SymfonyLevelSetList::UP_TO_SYMFONY_60);
$containerConfigurator->import(SymfonySetList::SYMFONY_CODE_QUALITY);
$containerConfigurator->import(SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION);
};

In theory, there shouldn't be any code differences needed between Symfony 5.4 and 6.0... though sometimes there are minor cleanups you can do once you have upgraded.

Let's run this and see what happens. Say:

vendor/bin/rector process src/

And... okay. It made one change. This is to our event subscriber: it added an array return type. This was done because, in the future, this interface may add an array return type. So now our code is future compatible.

... lines 1 - 9
class CheckVerifiedUserSubscriber implements EventSubscriberInterface
{
... lines 12 - 24
public static function getSubscribedEvents(): array
{
... lines 27 - 29
}
}

Upgrading via Composer

With that done, let's upgrade! In composer.json, we need to find the main Symfony libraries and change their version from 5.4.* to 6.0.*. Let's take the lazy way out and do that with a "Find & Replace".

111 lines composer.json
{
... lines 2 - 5
"require": {
... lines 7 - 21
"symfony/asset": "6.0.*",
"symfony/console": "6.0.*",
"symfony/dotenv": "6.0.*",
... line 25
"symfony/form": "6.0.*",
"symfony/framework-bundle": "6.0.*",
... line 28
"symfony/property-access": "6.0.*",
"symfony/property-info": "6.0.*",
"symfony/proxy-manager-bridge": "6.0.*",
"symfony/routing": "6.0.*",
"symfony/runtime": "6.0.*",
"symfony/security-bundle": "6.0.*",
"symfony/serializer": "6.0.*",
"symfony/stopwatch": "6.0.*",
"symfony/twig-bundle": "6.0.*",
... line 38
"symfony/validator": "6.0.*",
... line 40
"symfony/yaml": "6.0.*",
... lines 42 - 45
},
"require-dev": {
... lines 48 - 50
"symfony/debug-bundle": "6.0.*",
... line 52
"symfony/var-dumper": "6.0.*",
"symfony/web-profiler-bundle": "6.0.*",
... line 55
},
... lines 57 - 103
"extra": {
"symfony": {
... line 106
"require": "6.0.*"
}
}
}

Awesome! Like before, we're not touching any Symfony libraries that are not part of the main package and which follow their own versioning scheme. Oh, and at the bottom, this did also change extra.symfony.require to 6.0.*.

So, we're ready! Just like before, we could say:

composer up 'symfony/*'

But... I'm not going to bother with that. Let's update everything with just:

composer up

And... it fails! Hmm. One of the libraries I'm using is babdev/pagerfanta-bundle... and apparently it requires PHP 7.2... but we're using PHP 8. If you look further, there are some errors about pagerfanta-bundle[v2.8.0] requiring symfony/config ^3.4 || ^4.4 || ^5.1, but not Symfony 6. So what's happening here? It turns out that pagerfanta-bundle[v2.8.0] does not support Symfony 6. Gasp!

Run

composer outdated

to see a list of outdated packages. Oooh! babdev/pagerfanta-bundle has a new version 3.6.1. Go into composer.json and find that... here it is! Change its version to ^3.6.

111 lines composer.json
{
... lines 2 - 5
"require": {
... lines 7 - 9
"babdev/pagerfanta-bundle": "^3.6",
... lines 11 - 45
},
... lines 47 - 109
}

This is a major version upgrade. So it may contain some backwards compatibility breaks. We'll check into that in a minute. Try:

composer up

again and... it's doing it! Everything just upgraded to Symfony 6!

Fixing PasswordUpgraderInterface::upgradePassword()

And then... to celebrate... it immediately exploded while clearing the cache. Uh oh... I think we may have missed a deprecation:

In UserRepository, upgradePassword([...]): void must be compatible with PasswordUpgraderInterface.

If you want to see this in color, you can refresh the homepage to see the same thing.

By the way, in Symfony 5.4, we can now click this icon to copy the file path to our clipboard. Now, if I go back over to my editor, hit "shift" + "shift" and paste, I jump directly to the file - and even the line - where the problem is.

And... phew! PhpStorm is not happy. That's because the upgradePassword() method changed from requiring a UserInterface to requiring a PasswordAuthenticatedUserInterface. So we just need to change that and... done!

... lines 1 - 8
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
... lines 10 - 18
class UserRepository extends ServiceEntityRepository implements PasswordUpgraderInterface
{
... lines 21 - 28
public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void
{
... lines 31 - 37
}
}

Back at our terminal, if we run:

php bin/console cache:clear

Now it's happy. We're still getting some deprecations down here from a different library... but I'm going to ignore those. These come from a deprecated package that... I really just need to remove from this project entirely.

PagerFanta Updates

Let's go make sure the homepage works. It... doesn't!? We get

Attempted the load class QueryAdapter from namespace "Pagerfanta\Doctrine\ORM.

This shouldn't be a surprise... since we did upgrade pagerfanta-bundle from 2.8 to 3.6.

This is a situation where you need to find the GitHub page for the library and hope that they have an upgrade document. This one actually does. If you read this closely, you'd discover that a bunch of classes that were previously part of Pagerfanta have now been broken into independent libraries. So if we want to use this QueryAdapter, we need to install a separate package. Do that with:

composer require pagerfanta/doctrine-orm-adapter

Cool... and if we refresh now... another error? This one's even better:

Unknown function pagerfanta. Did you forget to run composer require pagerfanta/twig in question/homepage.html.twig?.

The Twig integration was also moved to its own package... so we need to run that command too:

composer require pagerfanta/twig

And... after that's done... it's alive! We have a Symfony 6 project! Woohoo! If we click around, things seem to be working just fine. We did it!

Checking for Outdated Packages

Over at our command line, run

composer outdated

to see all of the outdated packages we have left. The list is now very short. One package is knplabs/knp-markdown-bundle, which is fully upgraded... but it's been abandoned. If you have this in a real project, refactor it to use twig/markdown-extra. I'm not going to bother, but that's why it's on this list.

The biggest thing here is that doctrine/dbal has a new major version! So hey! While we're here upgrading things, let's upgrade it too! That's next, along with some final cleanups.

Leave a comment!

12
Login or Register to join the conversation
Maestro Avatar
Maestro Avatar Maestro | posted 1 month ago

I'm gettting this error:

- doctrine/migrations[3.2.0, ..., 3.3.0] require symfony/console ^3.4 || ^4.4.16 || ^5.0 -> found symfony/console[v3.4.0-BETA1, ..., 3.4.x-dev, v4.4.16, ..., 4.4.x-dev, v5.0.0-BETA1, ..., 5.4.x-dev] but it conflicts with your root composer.json require (6.0.*).

I can't seem to solve it

Reply

Hello @Maestro,

What exact command fails? That error is ok for upgrade process you just need to upgrade doctrine/migrations too

Cheers!

Reply
Nicolas-S Avatar
Nicolas-S Avatar Nicolas-S | posted 10 months ago | edited

Have you encountered this error when upgrading from 5.4 to 6.0 ?

Neither the property "authenticatorManagerEnabled" nor one of the methods "authenticatorManagerEnabled()", "getauthenticatorManagerEnabled()"/"isauthenticatorManagerEnabled()"/"hasauthenticatorManagerEnabled()" or "__call()" exist and have public access in class "Symfony\Bundle\SecurityBundle\DataCollector\SecurityDataCollector".

I understand the code enabling the new authenticator manager has been dropped in symfony 6, since it is now the only authentication system. But I have checked, I don't call that anywhere in my code.

Reply

Hey Nicolas,

Since the new authenticator system is enabled by default, you'll have to disable it or upgrade your security system

Cheers!

Reply
Nicolas-S Avatar

Thank you Mollokhan.

The thing is... I am using the new security system ! I followed the steps in this tutorial.

I will double check to see if some old code ( linked to fosuser maybe ) isn't causing this.

Reply
Nicolas-S Avatar

Turns out it was a freak cache issue.

I had cleared the cache with bin/console cache:clear many times, but only after doing rm -r var/cache/*did my web debug toolbar come back.

Reply

Ha! That's totally unexpected, but for some reason, Symfony's cache gets "stuck" from time to time. So, is a good idea to clear the cache manually when something does not make any sense.

Cheers!

Reply
Dan_M Avatar

Hey guys!

Oddly, after upgrading to Symfony 6, my web debug toolbar is not working. Instead of the toolbar, I get the symfony logo and the message "An error occurred while loading the web debug toolbar." How do I chase down that error?

Thanks!

Reply
Dan_M Avatar

Never mind! The symfony serve error log pointed out the problem. Somehow, I lost the enable_authenticator_manager: true line in my security.yaml file. When I put that back, the web debug toolbar worked.

Thanks for the great tutorial (as always!)

1 Reply
Nicolas-S Avatar

You can try to chase down a web debug toolbar breakdown by looking at the network tab in the navigator dev tools. You should see a xhr request (filter for xhr) for the debug toolbar and if you click on it, you should find its response and more convenient the preview of that response, which shows the error message.

Reply

Next chapter (17) is not allowed.

I see a message:
"This website symfonycasts.com/screencast... is currently offline. Cloudflare's Always Online™ shows a snapshot of this web page from the Internet Archive's Wayback Machine. To check for the live version, click Refresh."

Update:
All right now

Reply

Hey dzianisr

Sorry for this, we had an internal issue and it took some time to fix it.

Thanks for staying with us! Cheers and have a nice day!

Reply
Cat in space

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

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": "^8.0.2",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "babdev/pagerfanta-bundle": "^3.6", // v3.6.1
        "composer/package-versions-deprecated": "^1.11", // 1.11.99.5
        "doctrine/annotations": "^1.13", // 1.13.2
        "doctrine/dbal": "^3.3", // 3.3.5
        "doctrine/doctrine-bundle": "^2.0", // 2.6.2
        "doctrine/doctrine-migrations-bundle": "^3.2", // 3.2.2
        "doctrine/orm": "^2.0", // 2.11.2
        "knplabs/knp-markdown-bundle": "^1.8", // 1.10.0
        "knplabs/knp-time-bundle": "^1.18", // v1.18.0
        "pagerfanta/doctrine-orm-adapter": "^3.6", // v3.6.1
        "pagerfanta/twig": "^3.6", // v3.6.1
        "sensio/framework-extra-bundle": "^6.0", // v6.2.6
        "sentry/sentry-symfony": "^4.0", // 4.2.8
        "stof/doctrine-extensions-bundle": "^1.5", // v1.7.0
        "symfony/asset": "6.0.*", // v6.0.7
        "symfony/console": "6.0.*", // v6.0.7
        "symfony/dotenv": "6.0.*", // v6.0.5
        "symfony/flex": "^2.1", // v2.1.7
        "symfony/form": "6.0.*", // v6.0.7
        "symfony/framework-bundle": "6.0.*", // v6.0.7
        "symfony/mailer": "6.0.*", // v6.0.5
        "symfony/monolog-bundle": "^3.0", // v3.7.1
        "symfony/property-access": "6.0.*", // v6.0.7
        "symfony/property-info": "6.0.*", // v6.0.7
        "symfony/proxy-manager-bridge": "6.0.*", // v6.0.6
        "symfony/routing": "6.0.*", // v6.0.5
        "symfony/runtime": "6.0.*", // v6.0.7
        "symfony/security-bundle": "6.0.*", // v6.0.5
        "symfony/serializer": "6.0.*", // v6.0.7
        "symfony/stopwatch": "6.0.*", // v6.0.5
        "symfony/twig-bundle": "6.0.*", // v6.0.3
        "symfony/ux-chartjs": "^2.0", // v2.1.0
        "symfony/validator": "6.0.*", // v6.0.7
        "symfony/webpack-encore-bundle": "^1.7", // v1.14.0
        "symfony/yaml": "6.0.*", // v6.0.3
        "symfonycasts/verify-email-bundle": "^1.7", // v1.10.0
        "twig/extra-bundle": "^2.12|^3.0", // v3.3.8
        "twig/string-extra": "^3.3", // v3.3.5
        "twig/twig": "^2.12|^3.0" // v3.3.10
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.1
        "phpunit/phpunit": "^9.5", // 9.5.20
        "rector/rector": "^0.12.17", // 0.12.20
        "symfony/debug-bundle": "6.0.*", // v6.0.3
        "symfony/maker-bundle": "^1.15", // v1.38.0
        "symfony/var-dumper": "6.0.*", // v6.0.6
        "symfony/web-profiler-bundle": "6.0.*", // v6.0.6
        "zenstruck/foundry": "^1.16" // v1.18.0
    }
}
userVoice