Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Hunting the Final Deprecations

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

How can we be sure all our deprecated code is gone? The easiest way to catch most things is to surf around your site to see if you can trigger any other deprecation logs. Except... if a deprecation happens on a form submit where you redirect after... or if it happens on an AJAX call... you're not going to see those on the web debug toolbar.

Checking Deprecated Logs Locally

Fortunately, deprecations are also logged to a file. At your terminal, run:

tail -f var/log/dev.log

Symfony writes a lot of stuff to this log file... including any deprecation warnings: "User Deprecated". Hit Ctrl+C to exit the "tail" mode and run this again, but this time "pipe" it to grep Deprecated:

tail -f var/log/dev.log | grep Deprecated

We're now watching the log file for any lines that contain Deprecated. Unfortunately, because of that annoying doctrine/persistence stuff, it does contain extra noise. But it'll still work. You could filter that out by adding another | grep -v persistence.

Anyways, now we can try out the site: like clicking into an article... or doing anything else you can think of, like going to an admin section /admin/comments. Oh, duh - I'm not logged in as an admin. You get the point: use your site, then go back and check out the deprecations.

Yikes! I probably should have added that | grep -v persistence to remove all the noise. But if you look closely... yea... every single one of these is from doctrine/persistence!

So as best as we can tell, our site is deprecation free. But! There are a few more things to check to be sure.

Command Deprecations

For example, if you have some custom console commands, they might trigger some deprecated code. Open a new terminal tab and run:

php bin/console

This app has two custom console commands. Let's run this article:stats command... it just prints out a fake table:

php bin/console article:stats foo

It worked perfectly. But if you go back to the logs and look closely... ah! A real deprecation warning!

ArticleStatsCommand::execute() return value should always be of the type int since Symfony 4.4, NULL returned.

Interesting. Let's open that command: src/Command/ArticleStatsCommand.php:

... lines 1 - 11
class ArticleStatsCommand extends Command
protected static $defaultName = 'article:stats';
protected function configure()
... lines 18 - 22
protected function execute(InputInterface $input, OutputInterface $output)
... lines 27 - 48

Since Symfony 4.4, the execute() method of every command must return an integer. At the bottom, return 0:

... lines 1 - 11
class ArticleStatsCommand extends Command
... lines 14 - 24
protected function execute(InputInterface $input, OutputInterface $output)
... lines 27 - 49
return 0;

This ends up being the "exit code" that the command returns when you run it. Zero means successful and pretty much anything else - like 1 - means that the command failed.

Copy the return and open the other command class. At the bottom of execute(), return 0:

... lines 1 - 14
class AuthorWeeklyReportSendCommand extends Command
... lines 17 - 38
protected function execute(InputInterface $input, OutputInterface $output)
... lines 41 - 61
return 0;

And... let's make sure that we don't have any other return statements earlier. Nope, it looks good.

Production Deprecation Log

So we've surfed the site, checked the logs and run some console commands. Now are we sure that all the deprecated code is gone? Maybe? There are 2 final tricks.

First, as I mentioned earlier, at this point, I would deploy my code to production and watch the prod.deprecations.log file for any new entries... ignoring any doctrine/persistence stuff:

... lines 3 - 15
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.deprecations.log"
... lines 19 - 24

If nothing new is added, it's almost definitely safe to upgrade.

Deprecations in Tests

Another easy trick is to... run your tests! You... do have tests, right? Run:

php bin/phpunit

For me, it looks like it needs to download PHPUnit... and then... cool! This collects all the deprecations that were hit inside our tests and prints them when it's done. There are a lot of doctrine/persistence things... but that's it! There are no Symfony deprecations.

I am now willing to say that our app is ready for Symfony 5.0. So... let's upgrade next! Thanks to all our hard work, upgrading to a new major version of Symfony is just a Composer trick.

Leave a comment!

Login or Register to join the conversation

There is one more deprecation that happens when you run the command bin/console article:stats with the following error message

php.INFO: Deprecated: Array and string offset access syntax with curly braces is deprecated {"exception":"[object] (ErrorException(code: 0): Deprecated: Array and string offset access syntax with curly braces is deprecated at /Users/dontas.tassis/Projects/symfony-upgrade-4-5/vendor/michelf/php-markdown/Michelf/MarkdownExtra.php:677)"} []<br />

After a bit of research I found that the current latest version of KnpMarkdownBundle 1.8.1 has a composer dependency with michelf/php-markdown : ~1.4 which causes the deprecation. The latest library needs to be updated. Is that possible to happen as a KnpMarkdownBundle dependency or the library it self has to be updated?


Hey donatos

Nice research. In this case the michelf/php-markdown library should update its code and fix that deprecation, and then KnpMarkdownBundle should update such dependency and release a new version. Perhaps they already did


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