Chapters
-
Course Code
Subscribe to download the code!
Subscribe to download the code!
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Hey friends! If you're like me, you probably have a Symfony 5 project - or 10 - lying around just waiting to get upgraded to Symfony 6. Well... you've come to the right place! That's exactly what we're going to do in this tutorial! But more than that! This is a particularly interesting upgrade, because it also involves updating our code to use PHP 8. And that includes a transformation from using annotations to PHP 8 attributes. I need to find my monocle, because we're getting fancy. It also includes several other PHP 8 features, which you're really going to like. Plus, for the first time, we're going to use a tool called "Rector" to automate as much of this as possible. And... because I just can't help myself, we'll discover nice new Symfony 6 features along the way.
Getting the Project Running
All right! To get this upgrade party started, you should definitely code along with me. Download the course code from this page and unzip it to find a start/
directory with the same code you see here. Follow this README.md
file for all the setup goodies. I've already followed most of these steps... but I still need to build my Webpack Encore assets and start a web server. So let's do that!
Over in my terminal (this is already inside the project), run
yarn install
or
npm install
to download the Node packages. I want to get this running properly because we're going to upgrade some of our JavaScript tools a bit later.
Then run:
yarn watch
or
npm run watch
to build the frontend assets... and then watch for changes.
For the last step: open a new terminal tab and get a local web server started. I'm going to use the Symfony server like normal by running:
symfony serve -d
And... awesome! That starts a new web server at https://127.0.0.1:8000. I'll click that and say... "Hello" to Cauldron Overflow! My old friend! This is the site we've been building throughout our Symfony 5 series. And if you check its composer.json
file... and look down here for Symfony stuff... whoa.. it is old. All of the main Symfony libraries are version "5.0". That was ages ago. I was so young then!
The Plan
Here's our upgrade strategy. Step one: we're going to upgrade our project to Symfony 5.4. That's safe to do because Symfony doesn't include any backwards compatibility breaks on minor version upgrade. So anytime you upgrade just this middle number - called the "minor" number, like 5.0 to 5.4 - that's always going to be safe.
Step two: once we're on Symfony 5.4, to prepare our code for Symfony 6, all we need to do is hunt down and fix all of the deprecations in our code. Once we've fixed those, it will be safe to go to Symfony 6. To find those deprecations, we're going to use a few tools, like "Rector" to upgrade parts of our code, the new recipes update system and the tried-and-true Symfony "deprecations reporting".
After all of that, once we have a Symfony 5.4 project with no deprecations... we can just "flip the switch" and upgrade to Symfony 6. Easy peasy!
And at the very end, we'll cover a few more new features that you might like. Are you ready? Great! Let's upgrade our site to Symfony 5.4 next.
24 Comments
Hey @Slawomir-B ,
If I understand you correctly, the system is trying to use different credentials from the ones that are written in the .env
file, right? If so, there's a few more files that take precedence over the .env file, e.g. .env.local
, or Symfony environment specific .env files. Please, double-check all the .env files in your project to make sure you don't override your default DB credentials from the .env
file. You may also want to leverage the bin/console debug:dotenv
Symfony command which will show you the env vars declared in your system with their values and in which order they are loaded.
Also, you may even want to double-check the same .env file, sometimes you may accidentally declare the same env var twice in that file and the latter definition will override the 1st one.
If still no luck, please, double check your configuration files in the config/ dir - there might be some config changes there that also override your DB config.
I hope that helps!
Cheers!
Yes, it has something to do with symfony cli because both serve and doctrine commands use root database. If I use php81 bin/console doctrine...
and laragon it uses the symfony6_upgrade.
Hey Slawomir,
If you use symfony
binary - the connection may be different indeed in case you also have some Docker setup. In short, you may want to use plain bin/console
if you don't use Docker, or the reverse, it's recommended to use symfony console
in case you use Docker, because it will use dynamic ports that Docker reveals.
Cheers!
I'm going to have to counter that with: I'm using docker and it goes to root with symfony cli anyway and works properly with bin/console.
Hey Slawomir,
It's great it works with bin/console
for you. Actually, it should work for sure, but you need to specify correct credentials manually. While the symfony console
will automatically detect and exposed ports, so it's still recommended to use symfony console
especially if you're leveraging Docker. But if using bin/console
is more familiar to you - that's a good way too, just keep in mind to set up correct credentials manually.
Cheers!
Hey,
Few unclear questions
Which version of php need to run app ? Probably need to update video or text over with PHP version php -v
and probably list of needed extension like mysql and ....
P.s. I don't use mysql, Best practicies of Symfony use Postrgres. Why there are mysql? :)))))
Hey Mepcuk,
You can see a minimum required PHP version in the composer.json, but you don't even need to download the course code to know it, you can look at the "Versions" tab on this page to know that the project requires PHP "^8.0.2" in this project, as also you can see a list of all dependencies in this course. So, in theory, any PHP version which matches that constraint should be good, i.e. 8.0.2+, 8.1, 8.2. But if you experience any problems with your current PHP version that should work but does not - let us know in the comments and our support team will help :)
P.s. I don't use mysql, Best practicies of Symfony use Postrgres. Why there are mysql? :)))))
You can use whatever you want, of course! :) You just need to configure the DATABASE_URL in your .env.local file, you can see an example of its configuration commented out in .env. Why? Well, it's the most straightforward and widely used DB, so it's easier for newcomers to start with it because many server solutions like XAMP, MAMP, etc usually provide it out of the box.
Cheers!
The version of nodejs you have installed might cause some problems. When running yarn watch
I got this error
yarn watch
yarn run v1.22.19
$ encore dev --watch
Running webpack ...
node:internal/crypto/hash:71
this[kHandle] = new _Hash(algorithm, xofLen);
^
Error: error:0308010C:digital envelope routines::unsupported
at new Hash (node:internal/crypto/hash:71:19)
at Object.createHash (node:crypto:133:10)
at BulkUpdateDecorator.hashFactory (/home/arne/src/kurs/sf6_upgrade/node_modules/webpack/lib/util/createHash.js:155:18)
at BulkUpdateDecorator.digest (/home/arne/src/kurs/sf6_upgrade/node_modules/webpack/lib/util/createHash.js:80:21)
at /home/arne/src/kurs/sf6_upgrade/node_modules/webpack/lib/DefinePlugin.js:595:38
at Hook.eval [as call] (eval at create (/home/arne/src/kurs/sf6_upgrade/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:104:1)
at Hook.CALL_DELEGATE [as _call] (/home/arne/src/kurs/sf6_upgrade/node_modules/tapable/lib/Hook.js:14:14)
at Compiler.newCompilation (/home/arne/src/kurs/sf6_upgrade/node_modules/webpack/lib/Compiler.js:1053:26)
at /home/arne/src/kurs/sf6_upgrade/node_modules/webpack/lib/Compiler.js:1097:29
at Hook.eval [as callAsync] (eval at create (/home/arne/src/kurs/sf6_upgrade/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1) {
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'
}
This was with Node.js v18.7.0
installed.. I had to do export NODE_OPTIONS=--openssl-legacy-provider
before yarn watch
. Then it would run successfully.
In which file should I make my changes?
Hey @Atikingbadota
@Ahaaje means you need to add that to your command like:
NODE_OPTIONS=--openssl-legacy-provider yarn watch
No need to edit any files :)
Cheers!
I did not change any file. I just ran the export command before I started yarn
Hey Ahaaje!
Yea, sorry about this! I believe the problem is that in Node 17, there were some BC breaks related to ssl options. Webpack fixed this in version 5.61.0 and babel-loader in 8.2.4, but I believe this course code uses version older than that. We've got a task on our TODO list to check into this and see if we can carefully upgrade the code just a little bit to avoid this problem. Your work around, of course, is also good!
Cheers!
Hey guys! I'm off to a bumpy start on this tutorial. Composer failed executing the sentry recipe. It said, "Environment variable not found: 'SENTRY_DSN'."
I looked at the sentry.yaml file, and it calls for dsn: '%env(SENTRY_DSN)%' but there is no SENTRY_DSN in the .env files. What is an appropriate environment variable in this case?
Hey @Dan_M!
Ah, that's not the experience we want! I've recently learned the cause of this issue, and it's interesting and maddening! You're correct that SENTRY_DSN
is not included in .env
. And yes, if I download the code and run composer install
, it works just fine for me :).
Why? Because SENTRY_DSN
(this was done in an earlier tutorial) lives in the secrets vault. Anything in the secrets vault become env vars. So, why is this working for me and not for you? Because in order to read the secrets vault, your php install needs the Sodium extension - https://www.php.net/manual/en/sodium.installation.php - and my guess is that your php doesn't have this. What's maddening is that this should be installed by default in php since php 7.2. However, I've found some users with php 8 that don't have it - my guess is Ubuntu may ship with a stripped down version and you need to install it manually.
Anyways, this value isn't actually important for this tutorial. You can set SENTRY_DSN
to an empty value in .env
or run install the sodium php extension to get things working. I'm going to set SENTRY_DSN
to an empty string in .env
and update the code download just to avoid the issue for others. Oh, and if I'm TOTALLY wrong about the cause (Sodium), please tell me ;).
Cheers!
Hey @weaverryan!
I am developing on a Windows machine, and when I installed php 7.4, I did not enable the sodium extension in the php.ini file. When I did that, the code worked as expected.
Thanks!
Hi there I have an old project in symfony 3.4 with 19 bundles. I want to upgrade the project all the way to symfony 6 to keep with security updates and also take advantage of the new features. The project is used by more than 1000 users on a daily basis so it has to stay up throughout the upgrade process. Would you recommend upgrading step by step (following your tutorials, your upgrade to 4.0 tutorial is great by the way) or would using rector be an easier way to upgrade without breaking the project?
Hey Noel H.
Unfortunately I'm not Ryan but from my point of view I have some advices. First you need to check all your 19 bundles if they can be updated to use with Symfony 6+. Of course I'll recommend to use hybrid upgrade strategy, manually upgrading with wise applying Rector rules. Also it will be awesome if you have good test coverage. Anyways it will be better to have upgrade flow 3.4 -> 4.4 -> 5.4 -> 6.1 and then to keep all up to date I suggest to use 6/12 months upgrade periods.
Chers!
Thanks sadikoff for your response. I will take your advice into consideration.
You are welcome! I just had same situation several times, and even one upgrade from Symfony 2, but there was no rector at that time
Cheers!
Composer install fails:
Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Your lock file does not contain a compatible set of packages. Please run composer update.
Problem 1
- babdev/pagerfanta-bundle is locked to version v2.5.2 and an update of this package was not requested.
- babdev/pagerfanta-bundle v2.5.2 requires php ^7.2 -> your php version (8.1.2) does not satisfy that requirement.
Problem 2
- laminas/laminas-code is locked to version 3.5.1 and an update of this package was not requested.
- laminas/laminas-code 3.5.1 requires php ^7.3 || ~8.0.0 -> your php version (8.1.2) does not satisfy that requirement.
Problem 3
- stof/doctrine-extensions-bundle is locked to version v1.5.0 and an update of this package was not requested.
- stof/doctrine-extensions-bundle v1.5.0 requires php ^7.1.3 -> your php version (8.1.2) does not satisfy that requirement.
Problem 4
- laminas/laminas-code 3.5.1 requires php ^7.3 || ~8.0.0 -> your php version (8.1.2) does not satisfy that requirement.
- friendsofphp/proxy-manager-lts v1.0.1 requires laminas/laminas-code ^3.4.1|^4.0 -> satisfiable by laminas/laminas-code[3.5.1].
- friendsofphp/proxy-manager-lts is locked to version v1.0.1 and an update of this package was not requested.
Tried `composer update` and that resulted in
Your requirements could not be resolved to an installable set of packages.
Hey David P.!
Yea, this is our bad. The code DOES work in PHP 8, but you have to trick Composer (due to some dependencies being so old) with:
composer install --ignore-platform-reqs
I've just updated our setup README to show this.
Cheers!
Hey David P.
Thanks for reporting it. The first part of this tutorial is not compatible with PHP 8 until the part when it gets upgraded to Symfony 5.4
If you really want to make it work with PHP 8 you'll need to make a few changes to the composer.json
. Change all the Symfony libraries constraints "5.0." to "5.2. (including the config extra.symfony.require), then run composer up
I hope it helps. Cheers!
"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
}
}
for some reason it's trying to connect to root database despite having set different in
.env