Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Flex, Versioning & extra.symfony.require

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

Hi friends! Today we get to explore the, strange, mysterious, shiny world of Symfony 5. Duh, duh, duh!

Well... first we'll cover how to upgrade to Symfony 5 - which is its own fancy process - and then we'll chat about some of my favorite features.

Symfony 5: So What's New?

As far as upgrading goes, Symfony 5 doesn't make any huge changes: there isn't a totally new directory structure or some earth-shattering new paradigm like Symfony Flex and the recipe system. That's really because Symfony is in a great place right now.

So if you were looking forward to countless hours of work and huge changes to your app in order to upgrade it. Well... you're going to be disappointed. But if you're hoping for a smooth update process - and to learn about what's changed since Symfony 4.0 was released - welcome! After we're done, we should have some time left over to go eat cake.

The Release Cycle

But the fact that nothing crazy changed does not mean that nothing has been happening. Really... phew! The last 2 years since Symfony 4 was released have been huge... with the introduction of the Messenger component, Mailer and many, many other things.

Symfony releases a new "minor" version every 6 months months: 4.0 in November 2017, 4.1 in May 2018, 4.2 in November 2018, 4.3 in May 2019 and 4.4 in November 2019. It's the most boring release cycle ever... and I love it! symfony.com even has a roadmap page where you can check the timing of any past or future versions. Each of these minor versions comes packed with new features.

Will there be a Symfony 4.5? Nope! The .4 - like 3.4 or 4.4 - is always the last one. In fact, on the same day that a .4 minor is released, Symfony also releases the next major version. Yep, Symfony 4.4 and 5.0 were released on the same day. The reason deals with how upgrades work in Symfony. But more on that later.

Project Setup

So let's get to work! To composer update your upgrading skills - sorry... I couldn't help it - you should definitely download the course code from this page and code along with me. When you unzip the file, you'll find a start/ directory that holds the same code you see here.

This is a Symfony 4.3 project... but the app originally started on 4.0. So it has a decent amount of old... "stuff" that we'll need to upgrade. Open the README.md file for all the setup instructions. The last step will be to find a terminal, move into the project and use the Symfony binary to start a local web server:

symfony serve

That starts the server at https://127.0.0.1:8000. Find your browser and go there. Say hello to an application that will be very familiar to many of you: The SpaceBar: an alien news site that we've been working on since Symfony 4 was released two years ago.

What Does Upgrading Mean?

So, I have... kind of a silly question: what does it mean to upgrade Symfony? Because Symfony isn't just one big library: it's a huge number of smaller components.

Go to the project and open composer.json. Our app has grown pretty big: it has a lot of dependencies... and about half of these start with symfony/:

104 lines composer.json
{
... lines 2 - 3
"require": {
... lines 5 - 20
"symfony/asset": "^4.0",
"symfony/console": "^4.0",
"symfony/flex": "^1.0",
"symfony/form": "^4.0",
"symfony/framework-bundle": "^4.0",
"symfony/mailer": "4.3.*",
"symfony/messenger": "4.3.*",
"symfony/orm-pack": "^1.0",
"symfony/security-bundle": "^4.0",
"symfony/sendgrid-mailer": "4.3.*",
"symfony/serializer-pack": "^1.0",
"symfony/twig-bundle": "^4.0",
"symfony/twig-pack": "^1.0",
"symfony/validator": "^4.0",
"symfony/web-server-bundle": "^4.0",
"symfony/webpack-encore-bundle": "^1.4",
"symfony/yaml": "^4.0",
... lines 38 - 40
},
"require-dev": {
... lines 43 - 45
"symfony/browser-kit": "4.3.*",
"symfony/debug-bundle": "^3.3|^4.0",
"symfony/dotenv": "^4.0",
"symfony/maker-bundle": "^1.0",
"symfony/monolog-bundle": "^3.0",
"symfony/phpunit-bridge": "^3.3|^4.0",
"symfony/profiler-pack": "^1.0",
"symfony/var-dumper": "^3.3|^4.0"
},
... lines 55 - 102
}

When we talk about upgrading Symfony, we're really talking about upgrading all of the libraries that start with symfony/. Well, not all of the libraries: a few packages - like symfony/webpack-encore-bundle - are not part of the main Symfony code and follow their own versioning strategy:

104 lines composer.json
{
... lines 2 - 3
"require": {
... lines 5 - 35
"symfony/webpack-encore-bundle": "^1.4",
... lines 37 - 40
},
... lines 42 - 102
}

You can upgrade those whenever you want.

But the vast majority of the symfony/ packages are part of the main Symfony library and we usually upgrade them all at the same time. You don't have to, but it keeps life simpler.

Removing symfony/lts

Before we begin, if you started your project on Symfony 4.0, then inside of your composer.json file, you might have a package called symfony/lts. If you do, remove it with composer remove symfony/lts. I already removed it from this app.

symfony/lts was a, sort of "fake" package that helped you keep all of your many symfony packages at the same version. But this package was deprecated in favor of something different.

extra.symfony.require

Look inside your composer.json file for a key called extra and make sure it has a symfony key below it and another called require:

104 lines composer.json
{
... lines 2 - 95
"extra": {
"symfony": {
"id": "01C1TW989CK77ZA7B2H4HC9WAG",
"allow-contrib": true,
"require": "4.3.*"
}
}
}

This is a special piece of config that's used by Symfony Flex. Remember, Flex is the Composer plugin that give us the recipe system and a few other goodies. Flex reads extra.symfony.require and does two things. First, behind the scenes, it tells Composer that all the symfony/ repositories should be locked at version 4.3.*.

Scroll back up to the require section. See how symfony/form is set to ^4.0?

104 lines composer.json
{
... lines 2 - 3
"require": {
... lines 5 - 23
"symfony/form": "^4.0",
... lines 25 - 40
},
... lines 42 - 102
}

In Composer land, that format effectively means 4.*. If we ran composer update, it would upgrade it to the latest "4" version. So, 4.4.

But thanks to Symfony Flex and the extra.symfony.require 4.3.* config, symfony/form would actually only be updated to the latest 4.3 version.

The second thing this config does - and this is the true reason it exists - is optimize performance. When you run composer update or composer require, Flex filters out all versions of symfony/ packages that don't match 4.3.*. That actually makes Composer much faster as it has less versions to think about. If you've ever wondered why you used to run out of memory with Composer a few years ago... but don't now... this is why.

Let's see this 4.3.* require thing in action. Spin over to the terminal, open up a new tab and run:

composer update "symfony/*"

If we did not have Symfony Flex installed, we would expect that symfony/form would be updated to 4.4. But... yea! It says:

Restricting packages listed in symfony/symfony to 4.3.*

And... when we find symfony/form, it did upgrade it, but only to the latest 4.3 release - not 4.4. You can also see that it updated a few other libraries that start with symfony/* but that aren't part of the main Symfony code. Flex has no effect on these: they upgrade normally, and that's fine.

So upgrading the "patch" version of Symfony to get bug fixes and security releases is just as simple as running composer update "symfony/*". But to upgrade to the next minor version, we need to change the extra.symfony.require key. Except... there will be one other trick. Let's see what it is next.

Leave a comment!

27
Login or Register to join the conversation
Dmitriy Avatar
Dmitriy Avatar Dmitriy | posted 3 years ago

Hi! Are there any tools for creating redirects in Symfony 5?

For example, I need 301 redirects. Can this be implemented? There are a lot of such redirects and registering them on the server side is not very convenient.

1 Reply

Hey Dmitriy!

There are many possible tools here... but it depends on what you need to do :). Are you migrating your site to some new platform... and so many of the URLs are changing? Or something else? In Symfony, you can:

1) Create a route & controller, then use return $this->redirectToRoute('route_name', 301) to do a 301 redirect.
2) You can go even easier and do the whole redirect just by writing a route: https://symfony.com/doc/4.4/routing.html#redirecting-to-urls-and-routes-directly-from-a-route
3) Or if you want some dynamic system where you can create redirects in the database, we use ZenstruckRedirectBundle - https://github.com/kbond/ZenstruckRedirectBundle (though it still needs a Symfony 5 support release!)

Or... you can do other things :p. We run our DNS through Cloudflare, which allows us to do redirects at the (sort of) DNS level without writing any code.

Let me know what you're trying to do and if any of these fit.

Cheers!

Reply
Dmitriy Avatar

Thank you, Ryan.

I chose the second method and created redirects routes in routes.yaml.

I used package ZenstruckRedirectBundle before until I upgraded to Symfony 5 ( though it still needs a Symfony 5 support release). It’s good that I don’t have many redirects )

1 Reply
odds Avatar
odds Avatar odds | posted 2 years ago | edited

So, first i get this error:
! PHP Fatal error: Uncaught Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load class "DoctrineCacheBundle" from namespace "Doctrine\Bundle\DoctrineCacheBundle".<br />!! Did you forget a "use" statement for another namespace? in /drv/Data/odd.solutions/dev/symfony5-upgrade/start/src/Kernel.php:33<br />!! Stack trace:<br />!! #0 /drv/Data/odd.solutions/dev/symfony5-upgrade/start/vendor/symfony/http-kernel/Kernel.php(429): App\Kernel->registerBundles()<br />!! #1 /drv/Data/odd.solutions/dev/symfony5-upgrade/start/vendor/symfony/http-kernel/Kernel.php(130): Symfony\Component\HttpKernel\Kernel->initializeBundles()<br />!! #2 /drv/Data/odd.solutions/dev/symfony5-upgrade/start/vendor/symfony/framework-bundle/Console/Application.php(159): Symfony\Component\HttpKernel\Kernel->boot()<br />!! #3 /drv/Data/odd.solutions/dev/symfony5-upgrade/start/vendor/symfony/framework-bundle/Console/Application.php(65): Symfony\Bundle\FrameworkBundle\Console\Application->registerCommands()<br />!! #4 /drv/Data/odd.solutions/dev/symfony5-upgrade/start/vendor/symfony/console/Applicatio in /drv/Data/odd.solutions/dev/symfony5-upgrade/start/src/Kernel.php on line 33<br />!! <br />

Put a # in front of the line about DoctrineCacheBundle in bundles.php, but then this happens:
!! <br />!! In DefinitionErrorExceptionPass.php line 54:<br />!! <br />!! Cannot autowire service "App\Repository\ApiTokenRepository": argument "$reg <br />!! istry" of method "__construct()" references interface "Symfony\Bridge\Doctr <br />!! ine\RegistryInterface" but no such service exists. Try changing the type-hi <br />!! nt to "Doctrine\Persistence\ManagerRegistry" instead. <br />!! <br />!! <br />!!

And I'm giving up now.

Reply

Hey odds!

Don't give up! :) These are both normal errors - and we talk about them later in the tutorial - https://symfonycasts.com/sc...

The tl;dr is that a few type-hints need to be updated on your repository classes and can remove the DoctrineCacheBundle (when it was uninstalled, it should have been removed automatically from bundles.php, but if it wasn't you can remove it manually).

Let me know if that helps!

Cheers!

Reply
Akavir S. Avatar
Akavir S. Avatar Akavir S. | posted 3 years ago

I love symfony cast :)

Reply

Hey Virgile,

Haha, thank you for this feedback! I also noticed you had a problem before you edited the comment, glad you were able to solve it yourself, well done! ;)

Cheers!

Reply
Akavir S. Avatar

I'm trying to give you some rest :p

Thanks you a lot for your daily support Victor :)

Cheers!

Reply

Hey Virgile,

Hahaha, thanks! Do my best ;)

Cheers!

Reply
Robertas Š. Avatar
Robertas Š. Avatar Robertas Š. | posted 3 years ago

What did I do wrong?

C:\sym5>php bin/console doctrine:database:create
PHP Warning: require(C:\sym5/vendor/autoload.php): failed to open stream: No such file or directory in C:\sym5\bin\console on line 11

Warning: require(C:\sym5/vendor/autoload.php): failed to open stream: No such file or directory in C:\sym5\bin\console on line 11
PHP Fatal error: require(): Failed opening required 'C:\sym5/vendor/autoload.php' (include_path='C:\xampp\php\PEAR') in C:\sym5\bin\console on line 11

Fatal error: require(): Failed opening required 'C:\sym5/vendor/autoload.php' (include_path='C:\xampp\php\PEAR') in C:\sym5\bin\console on line 11
Reply

Hey Robertas Š.!

I think I might know the problem. After downloading the code, make sure you run composer install. That's mentioned in the README.md file, but you may have missed it :). Or, if you did run that and something else is wrong, let me know.

Cheers!

Reply
Robertas Š. Avatar

Yep, I forgot to add info from composer install command:

Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Your requirements could not be resolved to an installable set of packages.

Problem 1
- Installation request for lorenzo/pinky 1.0.5 -> satisfiable by lorenzo/pinky[1.0.5].
- lorenzo/pinky 1.0.5 requires ext-xsl * -> the requested PHP extension xsl is missing from your system.
Problem 2
- lorenzo/pinky 1.0.5 requires ext-xsl * -> the requested PHP extension xsl is missing from your system.
- twig/inky-extra v2.12.0 requires lorenzo/pinky ^1.0.5 -> satisfiable by lorenzo/pinky[1.0.5].
- Installation request for twig/inky-extra v2.12.0 -> satisfiable by twig/inky-extra[v2.12.0].

To enable extensions, verify that they are enabled in your .ini files:
- C:\xampp\php\php.ini
You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode.
Reply

Hey Robertas Š.

Looks like you need to install the XSL PHP extension first. This guide may help you out https://bobcares.com/blog/php-extension-xsl/ but it depends on your OS

Cheers!

Reply
Romain L. Avatar
Romain L. Avatar Romain L. | posted 3 years ago | edited

Hi !

I have an issue in the setup of the project.

When I execute doctrine:fixtures:load (with the project source code / start), I have this error :

`Careful, database "symfonycasts_symfony5-upgrade" will be purged. Do you want to continue? (yes/no) [no]:
> yes

> purging database
> loading App\DataFixtures\UserFixture
> loading App\DataFixtures\TagFixture

In Parser.php line 3195:
Notice: Trying to access array offset on value of type null

doctrine:fixtures:load [--append] [--group GROUP] [--em EM] [--shard SHARD] [--purge-with-truncate] [-h|--help] [-q|--quiet] [-v|vv|vvv|--verbose] [-V|--version] [--ansi] [--no-ansi] [-n|--no-interaction] [-e|--env ENV] [--no-debug] [--] <command>`

I'm in php 7.41, and mariadb 10.4.10

Thank's a lot

Romain

Reply

Hey Romain L.!

Thanks for the report! It looks like there is a bug in PHP 7.4 and doctrine/orm - it requires doctrine/orm version 2.7.1 or higher to fix it. We're going to work to upgrade affected tutorials, but you can (for now) work around the issue by running:


composer up doctrine/orm --with-dependencies

Cheers!

Reply
Dariia M. Avatar
Dariia M. Avatar Dariia M. | posted 3 years ago | edited

Hello! I have some problem with installing project code source. Articles' thumbnails (for example http://localhost:8000/media/cache/resolve/squared_thumbnail_small/article_image/mercury-5e84d2b2a3664.jpeg) give response with 500 error 'Unable to create image for path "article_image/mercury-5e84d2b2a3664.jpeg" and filter "squared_thumbnail_medium". Message was "An image could not be created from the given input"'. I have PHP 7.3.6, GD extension settings:
`php --ri gd

gd

GD Support => enabled
GD Version => bundled (2.1.0 compatible)
GIF Read Support => enabled
GIF Create Support => enabled
PNG Support => enabled
libPNG Version => 1.6.28
WBMP Support => enabled
XBM Support => enabled

Directive => Local Value => Master Value
gd.jpeg_ignore_warning => 1 => 1`
Can someone help with fixing this error, please?

Reply
Dariia M. Avatar

I figured out how to fix my problem. The GD extension wasn't properly installed. I use docker-compose for my project environment and this response helped me.

Reply

Hey Dariia M.

That is awesome that you solved issue by yourself, however feel free to ask any questions, we will be happy to help!

Cheers!

1 Reply
Markus L. Avatar
Markus L. Avatar Markus L. | posted 3 years ago

Hey there!

Part of my team is arguing for not upgrading too frequently, but rather from LTS (4.4) directly to next LTS (5.4) as a good practice for enterprise systems.

Is this the right way, or is it preferrable to take the minor version steps that are denoted to be somewhat short-lifed? While I personally am not happy with the idea of waiting two years for upgrading to Symfony5, reasonable arguments against it are having frequent updating work for being on short-lifed minor versions all the time.

Do you have a recommendation, which update strategy to follow best ?

Thanks for the good work!

Reply

Hey Markus L.!

I would *love* to tell you that upgrading to every minor version is the best idea... it's way more fun :). But honestly, from an enterprise system perspective, going from LTS to LTS is the "most stable" way to go. That's exactly why the support intervals for the LTS's overlap by 1 year: so that large projects can wait until 5.4 and then have 1 year to go from 4.4 to 5.4. The minor versions DO have such short lives... that if you're trying to stay on top of them, it can be difficult in a big project :).

WE upgrade every minor version... but WE make tutorials... so if we're not on the latest versions, shame on us ;). Enterprise is different.

One exception to this rule would be if a new feature comes out. For example, if you were on Symfony 3.4 and then wanted to use Symfony Messenger in 4.3 (pretend that is the latest version currently), then your team could make a one-time decision to jump from 3.4 to 4.3 to get that new feature.

I hope that helps!

1 Reply

Hello!
I have an issue.

I try execute "composer update symfony/*" as its said in tutorial. But response is: "zsh: no matches found: symfony/*"

MacOS Catalina 10.15.2
Symfony 4.3.*
composer 1.9.3

Reply

Hey Xiro

Try wrapping it between double quotes
# composer update "symfony/*"

Cheers!

1 Reply

Oh, thanks! That helped!

Reply
Dmitriy Avatar
Dmitriy Avatar Dmitriy | posted 3 years ago

Hi my composer.json section does not contain "require" attribute. Сan i add this manually?

"extra": {
"symfony": {
"id": "01C9D5CVHAG...",
"allow-contrib": false
}
}

Reply

Hey Dmitriy,

What Symfony version do you have? Do you have Symfony Flex installed in your project? In theory you could add it manually, but it just might not work. IIRC the Symfony Flex is responsible of that, so try to install (or update to the latest) Symfony Flex first, it should add that automatically. If not - you can try to add that manually I think.

Cheers!

Reply
Azarual E. Avatar
Azarual E. Avatar Azarual E. | posted 3 years ago

Hi there, i hope that you will make a complete tutorial about security including make:user make:auth make:registration-form and another thing that is very important email confirmation for every subscriber before he gets the right to logIn

Reply

Hey The early Bird!

Thank you for your interest in SymfonyCasts tutorials! We do have a tutorial about security, and we do cover many things related to users registration, authentication, and authorization. Have you watched that course by chance? It's called "Symfony Security: Beautiful Authentication, Powerful Authorization", you can find it here: https://symfonycasts.com/sc...

If you do, could you leave a feedback about what in particular was not covered by that course that you would like to see in the new tutorial?

P.S. About "email confirmation" - yeah, this topic is not covered in our tutorials yet, mostly because it's pretty straightforward feature. But we're going to include this topic in new Symfony 5 series :) And we already started working on Symfony 5 tutorials, you can check the first one here: https://symfonycasts.com/sc...

Cheers!

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