How we Upgraded to Symfony 2.7 (+ deprecation notices)
Written by weaverryan, and Leannapelham
Go Deeper!
When you're ready, also check out How to Upgrade to Symfony 2.8, then 3.0!
Symfony 2.7 - the next LTS release - came out on Saturday, with bells and whistles like 100+ new features/enhancements and a surprise new bridge component to PSR-7.
So, we decided to upgrade immediately and report back. Let's go!
Upgrading composer.json
Since Symfony protects backwards-compatibility, upgrading is mostly easy, but we did hit a few minor things. Btw, there's a new upgrade section on the docs - tell your friends!
Start by updating your composer.json
changes to allow for 2.7.*
:
{
"require": {
"php": ">=5.3.3",
"symfony/symfony" : "2.7.*",
"...": "..."
}
}
Now update this with composer. The command may surprise you:
composer update symfony/symfony sensio/distribution-bundle --with-dependencies
This will upgrade your project, but there are two important things happening:
1. You need to upgrade sensio/distribution-bundle
The version doesn't matter, just any new tag, 2.3.14
or higher. Why?
Symfony 2.7 comes with deprecation warnings, which are awesome for knowing
what deprecated features you're using. But, it also means that you need to
silence E_USER_DEPRECATED
warnings. The latest version of
sensio/distribution-bundle
builds an app/bootstrap.php.cache
file
that silences E_USER_DEPRECATED
warnings for you. Don't worry: you'll
still see the deprecated warnings in your web debug toolbar (see the image
on this post).
So, if you see a friend who's getting a lot messages that look like this:
Deprecated: The Definition::setFactoryMethod method is deprecated since
version 2.6 and will be removed in 3.0.
Tell them to upgrade their sensio/distribution-bundle
. And of course,
to eventually fix these deprecated calls.
2. You Need --with-dependencies
This flag tells composer to update symfony/symfony
and all libraries
that it depends on. You may not need this, but without it, we got a dependency
error involving twig/twig
. The version of Twig in our project was not
compatible with Symfony and needed to be upgraded. To allow for this, you have
two options: use --with-dependencies
, or explicitly upgrade the library
in question (e.g. twig/twig
):
composer update symfony/symfony twig/twig sensio/distribution-bundle
So What Broke?
Yay, you upgraded! Now, what broke? In our case, not much: in fact, only things in third-party bundles.
Upgrading FOSUserBundle
A new enhancement in Symfony 2.7 caused an accidental bug in FOSUserBundle. This was fixed two months ago, but you'll need to upgrade FOSUserBundle to get it.
If you're using a 1.3
release, just run the update
command below
(a tag was just released with the fix). If you're using the master (or 2.0)
branch, that's not stable yet, and has no tag. Make sure your composer.json
file has something like "friendsofsymfony/user-bundle": "~2.0@dev"
.
Then let composer work its magic:
composer update friendsofsymfony/user-bundle
But check the UPGRADE log on the bundle to see what might have changed.
Fixing Behat 2.5
We're using Behat 2.5, which suffered from a minor BC break in Symfony 2.7. If you get this error:
Runtime Notice: Declaration of InputDefinition::getSynopsis()
should be compatible with InputDefinition::getSynopsis($short = false)
then welcome to the club! Fortunately, this issue has been fixed (thanks to Stof for the fast release), so you just need to upgrade:
composer update behat/behat
If you're using the symfony2 driver, Behat may also explode on the new deprecated
notices. To fix this, add the following at the top of your FeatureContext
class::
define('BEHAT_ERROR_REPORTING', E_ALL & ~E_USER_DEPRECATED);
Back to the tests! And welcome to Symfony 2.7.
If you hit other issues, comment below and maybe we can help others.
Cheers!
25 Comments
Fast! And I've updated the post to reflect that. Thanks!
thanks for this post. Until I read this, I was still confused about the toolbar ("Don’t worry: you’ll still see the deprecated warnings in your web debug toolbar"). So, the methods that are being used in session/distribution-bundle and even the new Symfony 2.7.1 are designed to suppress the writing of these errors to the log, but not to prevent them from appearing in the toolbar? Is there a way to prevent the latter? In prod mode, my app works pretty well, but in dev mode (with the toolbar) the app often times out due to excessive error reporting. Since many of these errors come from sources I cannot control (e.g. Symfony itself), I would prefer to just prevent them entirely at this point I guess (unless there are better solutions).
Hey Craig!
Based on your 2.7.1 comment, I can see you have been watching this topic closely :). With 2.7.1, all trigger_error calls have the @trigger_error in front of them. Obviously, this silences them. BUT, you can still have your own custom error handler that hooks into these errors (even though they're silenced). That's what the web profiler is doing. Well actually, it's the Debug component, which logs all notices through the logger, and then a data collector which puts this into the WDT. I think it probably *is* possible to stop logging only E_USER_DEPRECATED, but it looks tricky enough (look at the ErrorHandler class).
How many deprecation warnings are you getting that causes the timeout? And is the count only high when the container is being built? Even if these are coming from inside of Symfony, Symfony itself doesn't use deprecated functionality (or only in a few small places - the test suite actually tests for this). So, the warnings must be coming from a result of your code or other third-party code, both which you should be able to fix (even the third-party libraries should be making new releases with the deprecated calls gone).
Cheers!
weaverryan, thank you so much for taking the time to respond!
I think the number of DEPRECATED notices is directly tied to the routes in our application which are saved/retrieved from DB. Depending on the number of extensions I have loaded in my app, I have varying number of errors. On my local laptop install I have 1053 on first build of the container and 702 on later reloads. MOST say "DEPRECATED - The "_method" requirement is deprecated since version 2.2 and will be removed in 3.0. Use the setMethods() method instead. " which I'm told has been intentionally left in Symfony.(https://github.com/symfony/.... Others are mostly setPath() or getPath() errors. (
DEPRECATED - The Symfony\Component\Routing\Route::getPattern method is deprecated since version 2.2 and will be removed in 3.0. Use the getPath() method instead. DEPRECATED - The Symfony\Component\Routing\Route::getPattern method is deprecated since version 2.2 and will be removed in 3.0. Use the getPath() method instead.)
We do have native route handling, but I'm not sure if it is directly causing the errors or if it is Symfony. Our project is here: https://github.com/zikula/core
Hey Craig!
I just had a look and commented up on your GitHub https://github.com/zikula/c.... We can keep chatting there. I could be wrong - but I'm not convinced yet that these errors are unavoidable (i.e. coming from Symfony and can't be silenced). And if that *is* the case, I'd consider that a bug in Symfony.
Cheers!
Thanks Ryan, the "Upgrade" guide in the cookbook didn't help when trying to go from 2.3 to 2.7. Your composer call worked.
For anyone else using knp_paginator, to make it work with Symfony 2.7 see https://github.com/symfony/... and http://stackoverflow.com/qu...
definitely worth to mention is also problem with factory_service and factory_method used in config files https://github.com/symfony/...
it is not obvious at all and it took me a while to figure this out why am i getting all this errors when doing any console update
I got a lot of these too. I believe that 2.7.1 (released today) has improved these messages (yay!).
also framework.templating.assets_version and framework.templating.assets_base_urls are throwing deprecated warnings even though there is no info anywhere how this should be corrected. official config documentation sates that nothing has changed about this http://symfony.com/doc/curr...
however the settings seems to be changed to framework.assets.version and framework.assets.base_urls where framework.assets.base_urls.http is scalar and not array as before
You're totally right! Sometimes a feature slips through without making it into the UPGRADE log. We have a pull request (it just needs to be finished) to update the docs - https://github.com/symfony/.... For the factory_service deprecation warnings (the issue is indeed that it's not clear what to fix), these have been improved - you should see better deprecation warnings for that in the next patch version.
But if you're reading this - this type of stuff doesn't block upgrade - this is all about the *next* step where you take your shiny new 2.7 project and slowly remove those deprecation warnings.
Cheers!
I upgraded to 2.7 and the debug tool has one deprecated notice but I am not able to find where am I using it.
Hey Shairyar!
That *is* one of the problems - the message you're getting might be that a method is deprecated, but it could be some little configuration that's causing that. That's something that's already being improved - Symfony 2.7.1 (which came out earlier today) has improved a few deprecation messages to be more clear. The other issue is that third party bundles you're using may be what's causing the deprecated notices. Often, if you check those libraries, those issues may already be fixed, or there may be pull requests open to fix them. Oh, and search the GitHub issues on the symfony/symfony repo - someone else may have opened an issue about your exact deprecation notice being unclear.
Cheers!
Thanks, the thing is I recently started a project and did not get to the step where I need third party bundles yet, I will however upgrade to 2.7.1 and see if I can track it down. By the way is 2.7 or 2.7.1 stable enough to be used in a project?
It's absolutely stable enough. There's always a few surprise accidental BC breaks that we need to catch up and document *right* when a release comes out, but it's all good. This site has been on 2.7 since the day it came out :). What's harder sometimes is that *new* features might not be fully doc'ed yet. For example, there are some changes to how the form component works. The old way still works, but the new way (which you'll need to know someday to remove deprecation notices) isn't fully doc'ed yet. But you can still upgrade safely.
Cheers!
Thanks for the feedback. Looking forward to work with 2.7
Hi again,
I have been seeing lots of "DEPRECATED - The ability to pass file names to the Symfony\Component\Yaml\Yaml::parse method is deprecated since version 2.2 and will be removed in 3.0. Pass the YAML contents of the file instead." in my logs, however I am unable to know from which call is this coming?
Is there any way you can tell what is causing this?
Im getting something like 300+ deprecated calls in each request !
Many thanks,
Hey Ziad!
Not all the deprecation warnings are totally clear - some of these are being improved (2.7.1 improved at least a few over 2.7.0). The problem is that Yaml::parse is deprecated, but probably it is something we're doing in a configuration file far away that is causing this :).
For now, you can search the symfony/symfony repository to see if anyone has asked this question and gotten an answer - but I don't see this one specifically. If you allow the warnings to be actually printed, then you can get a stacktrace, which will help a lot. But in 2.7.1, the errors have been silenced (they only show up in the toolbar). Long way of saying that we have a todo in the docs to give people more direction on how they can get full strack traces of these errors and debug them. For now, don't worry about it too much - it only *needs* to be done before the 3.0 upgrade.
Oh, but I just thought of one last thing. If you want - you can open up Yaml::parse, find that trigger_error() line, and temporarily throw a "new \Exception()". This will give you a stack-trace, which may show you where the call is actually coming from. You still may need to dig a few levels deep, however.
Let me know if you find anything out!
Cheers!
Hi Ryan,
I found out that the 'YamlDriver' in 'Doctrine\ORM\Mapping\Driver' still uses Yaml:parse($file) in its loadMappingFile($file) method.
Upon adding file_get_contents, all of my yml deprecated logs disappeared.
I am using "doctrine/orm" : "2.4.*" and "doctrine/doctrine-bundle": "1.2.*" in my composer.json file.
Same thing applies to gedmo/doctrine-extensions (I have reported this).
Thanks for your help. Now its time to fix all these issues I got in the upgraded form component :)
If anyone looking for a general guide on upgrading symfony from any 2.x version 3.x then here is a good one I found online: https://www.cloudways.com/b...
Using this guide you can upgrade to even 3.1 from 2.8.
Thanks for this post. I've written a similar tutorial about upgrading from 2.6 to 3.0: http://manuel.kiessling.net...
Note that the Behat hack is not needed anymore. I just released Behat 2.5.5 with the fix included in it.