Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Managing Flex, extra.symfony.require & Version Constraints

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.

We just ran:

composer update "symfony/*"

Thanks to the extra.symfony.require key in our composer.json file:

104 lines composer.json
{
... lines 2 - 95
"extra": {
"symfony": {
... lines 98 - 99
"require": "4.3.*"
}
}
}

Which is currently set to 4.3.*, it only upgraded things to the latest 4.3 version - not 4.4. Let's change this to 4.4.*:

104 lines composer.json
{
... lines 2 - 95
"extra": {
"symfony": {
... lines 98 - 99
"require": "4.4.*"
}
}
}

But wait... why are we upgrading to Symfony 4.4? Isn't this a tutorial about upgrading to Symfony 5? Why not just go straight there? The reason is due to Symfony's, honestly, incredible upgrade policy. Symfony never breaks backwards compatibility for a minor release - like from 4.3 to 4.4. Instead, it deprecates code... and you can see what deprecated code you're using with some special tools. By upgrading to 4.4, we'll be able to see the full list of deprecated things we need to fix. Then we can fix them before upgrading to Symfony 5. We'll see this later.

Anyways, find your terminal and, once again, run:

composer update "symfony/*"

Yea! This time it is updating the Symfony packages to 4.4. That was easy!

composer.json Version Constraints for symfony/ Packages

Except... come on... it's never quite that easy. In fact, some Symfony packages did not upgrade. Check it out. Run:

composer show symfony/mailer

Scroll up: woh! This is still on version 4.3! Why?

Open up the composer.json file and find symfony/mailer:

104 lines composer.json
{
... lines 2 - 3
"require": {
... lines 5 - 24
"symfony/framework-bundle": "^4.0",
"symfony/mailer": "4.3.*",
... lines 27 - 40
},
... lines 42 - 102
}

Interesting: some packages - like symfony/form or symfony/framework-bundle are set to ^4.0 - which more or less means 4.*. But the symfony/mailer version is 4.3.*.

Symfony Flex: composer.json Version Formatting

There are two things I need to say about this. First, usually when you run compose require some/package, when Composer updates your composer.json file, it uses the "caret" (^) format. That's why you see ^3.0 and ^1.1.

But, when you use Symfony Flex and composer require a Symfony package, it changes that to use the * format - like 4.3.*. That's not a huge deal. In fact, it's almost an accidental feature - but it is nice because the best-practice is typically to control the "minor" version of your Symfony packages - that's the middle number - so that you can upgrade them all at the same time.

But... Flex didn't always do this. That's why, in my project, you see a mixture: some libraries like symfony/form have the "caret" format and other libraries - that were installed more recently like symfony/mailer - use the "star" format.

Symfony Flex: symfony.extra.require is a "Soft" Requirement

The second thing I need to tell you is that the extra.symfony.require config - set to 4.4.* now - is... more of a "suggestion". It doesn't force all Symfony packages to this version. More accurately it says:

When any symfony/ package is updated, its upgrade will be restricted to a version matching 4.4.*

But if you have a package that is specifically locked to 4.3.*, it won't override that and force it to 4.4.*. That is why symfony/mailer didn't upgrade.

Changing symfony/ composer.json Versions

If all this explanation doesn't make total sense... or you just done care - Hey, that's ok! Here is what you need to know: whenever you upgrade Symfony to a new minor version - like 4.3 to 4.4, you need to do two things: (1) update the extra.symfony.require value and (2) update all the package versions to 4.4.*.

If that seems a bit redundant, it... kinda is! But changing the version next to the package to 4.4.* gives you clear control of what's going on... and it's how Composer normally works. And then, the extra.symfony.require config gives us a big performance boost in the background.

Let's do this next, upgrade to Symfony 4.4 and fix a few packages that ended up inside our "dev" dependencies incorrectly.

Leave a comment!

11
Login or Register to join the conversation
Richard Avatar
Richard Avatar Richard | posted 2 years ago

Should I be able to delete composer.lock, update composer.json to your code download , remove vendor and then composer install? There really is nothing "easy" about this upgrade it seems to puzzle after puzzle to get to the endpoint ;)

1 Reply

Hey Richard!

Hmm, in theory, yes, that would work :). That it the most aggressive way to upgrade. What I mean is, you will be upgrading ALL your dependencies, and you could have some BIG upgrades. But it should work and *would* be simple. I would also *at least* upgrade a few of the most important recipes - like framework-bundle and symfony/console.

If you try it, let me know how it goes!

Cheers!

Reply
esskayaitch Avatar
esskayaitch Avatar esskayaitch | posted 1 year ago

These things are moving targets. I just tried the composer.json line "require": "4.4.*" with the result...

$ composer update symfony/*
Loading composer repositories with package information
Restricting packages listed in "symfony/symfony" to "4.4.*"
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

... followed by a string of conclusion and conflict messages, ending with...

- Root composer.json requires symfony/framework-bundle ^4.0 ->satisfiable by symfony/framework-bundle[v4.4.0, ..., v4.4.25].
- Root composer.json requires symfony/messenger 4.3.* -> satisfiable by symfony/messenger[v4.3.0, ..., v4.3.11].

What next?

Reply

Hey,

I think, I'd need to see the full output of Composer to find which one is the problematic dependency.
Cheers!

Reply
esskayaitch Avatar
esskayaitch Avatar esskayaitch | MolloKhan | posted 1 year ago

That's most of it really. But it seems that even though the video doesn't get these errors, re-factoring the version string from '^4.4" to '4.4.*' did fix the problem. Thanks anyway.

1 Reply

Great! If you have any other doubt, let us know :)

Reply
Default user avatar
Default user avatar Simo He | posted 2 years ago

You write that

symfony.extra.require is a soft requirement

(in Symfony Flex: symfony.extra.require is a "Soft" Requirementhttps://symfonycasts.com/sc.... Would this mean I can install a package in a different symfony version? My tries show that this does not work, see

Reply

Hey @Simo He

Yes it's correct it's soft requirement for automatic upgrading already installed libraries, but it will not give you ability to install whatever symfony library you want, because flex will limit the list of versions according to this require section. But it will not work for libraries which don't have this version in their list.

Cheers!

1 Reply
Sung L. Avatar
Sung L. Avatar Sung L. | posted 2 years ago

In my PhpStorm IDE, exact version number is not displayed like the one in this video. In this video, when a cursor is in a line, it shows exact version number in light grey color. Do I need to install a plugin? Thanks!

Reply

Hey Sung L.

Yeah! You need to install the composer plugin for PHPStorm :)

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
    }
}