Fixing Third Party Bundle Deprecations (Indirectly)


At this point we've fixed the issues that you might find when upgrading most any project from Symfony 3.4 to 4.0. And we've also fixed some problems specific to our own implementation. Now we must fix (indirectly) any problems with third party bundles we are using.

In our case we have one problem we need to address:

User Deprecated: Implementing "Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface" without the "reset()" method is deprecated since version 3.4 and will be unsupported in 4.0 for class "EightPoints\Bundle\GuzzleBundle\DataCollector\HttpDataCollector".

I've seen this same warning for a number of different bundles. Any bundle that provides additional metrics and data on your web debug toolbar will likely suffer from this problem.

Do we need to fix this ourselves?

Hopefully not.

It may be sufficient to simply update the bundle.

In this case we are using:

"eightpoints/guzzle-bundle": "^4.5"

And checking packagist reveals that version v7.2.1 is the latest at the time of recording.

Ok, so this is three major versions further on than where we are currently.

Any time a major version bump is involved you can expect some breaking changes. Ahem, just like what we're encountering in the wider context of this series :)

The biggest breaking change is that "eightpoints/guzzle-bundle": "^7.0.0" requires PHP 7.0 or greater.

Now this is interesting, but wait, there's more!

Symfony 4 now requires PHP 7.1 or greater.

php -v

PHP 7.2.0-2+ubuntu16.04.1+deb.sury.org+2 (cli) (built: Dec  7 2017 20:14:31) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.2.0-2+ubuntu16.04.1+deb.sury.org+2, Copyright (c) 1999-2017, by Zend Technologies

I'm ok on my local machine. You are more likely to encounter problems here if deploying to production, and you don't fully control the server. This is outside the scope of this tutorial.

What happens next is specific to each bundle.

Fortunately the latest version of eightpoints/guzzle-bundle comes with support for Symfony 4, and Symfony Flex. Before worrying any further about this I'm simply going to bump up to v7.2.1 and fix any problems.

Bundle Upgrade

The first change I'm making is to bump up the version of eightpoints/guzzle-bundle in composer.json:

    "require": {
-        "eightpoints/guzzle-bundle": "^4.5",
+        "eightpoints/guzzle-bundle": "^7.2.1",
    },

Now, I'm going to run composer update to bring in the latest changes:

composer update

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

  Problem 1
    - Installation request for eightpoints/guzzle-bundle ^7.2.1 -> satisfiable by eightpoints/guzzle-bundle[v7.2.1].
    - eightpoints/guzzle-bundle v7.2.1 requires php >=7.0 -> your PHP version (7.2.0-2+ubuntu16.04.1+deb.sury.org+2) overridden by "config.platform.php" version (5.5.9) does not satisfy that requirement.

Huh.

The error here is that we have PHP 7.2 locally, but config.platform.php is hardcoded to 5.5.9.

This value lives in our composer.json file:

    "config": {
        "platform": {
            "php": "5.5.9"
        }
    },

Is the right move simply to bump up this number to whatever PHP version we're using?

Well, I guess we could. But the more preferable way, in my opinion, is to remove this section entirely.

Why?

Well we can use the require section to specify which PHP version we need:

    "require": {
-        "php": ">=5.5.9",
+        "php": "^7.1.3",

Not only is this how a fresh installation of Symfony 4 would set this value, but it also removes the unusual duplication.

Ok, now we can composer update our problems away, right?

composer update

Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 0 installs, 1 update, 1 removal
  - Removing eightpoints/guzzle-wsse-middleware (v4.2.0)
  - Removing eightpoints/guzzle-bundle (v4.6.0)
  - Installing eightpoints/guzzle-bundle (v7.2.1) Loading from cache
Writing lock file
Generating autoload files
> Incenteev\ParameterHandler\ScriptHandler::buildParameters
Updating the "app/config/parameters.yml" file
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::buildBootstrap
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache
PHP Fatal error:  Uncaught Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load class "GuzzleBundle" from namespace "EightPoints\Bundle\GuzzleBundle".
Did you forget a "use" statement for another namespace? in /home/chris/Development/crv-symfony-4-updates/githut/app/AppKernel.php:19
Stack trace:
#0 /home/chris/Development/crv-symfony-4-updates/githut/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php(494): AppKernel->registerBundles()
#1 /home/chris/Development/crv-symfony-4-updates/githut/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php(134): Symfony\Component\HttpKernel\Kernel->initializeBundles()
#2 /home/chris/Development/crv-symfony-4-updates/githut/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php(63): Symfony\Component\HttpKernel\Kernel->boot()
#3 /home/chris/Development/crv-symfony-4-updates/githut/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(148): Symfony\Bundle\FrameworkBundle\Console\Application->doRun(Ob in /home/chris/Development/crv-symfony-4-updates/githut/app/AppKernel.php on line 19
Script Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache handling the post-update-cmd event terminated with an exception

  [RuntimeException]                                                                                                                                
  An error occurred when executing the "'cache:clear --no-warmup'" command:                                                                         
  PHP Fatal error:  Uncaught Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load class "GuzzleBundle" from namespace "Eigh  
  tPoints\Bundle\GuzzleBundle".                                                                                                                     
  Did you forget a "use" statement for another namespace? in /home/chris/Development/crv-symfony-4-updates/githut/app/AppKernel.php:19              
  Stack trace:                                                                                                                                      
  #0 /home/chris/Development/crv-symfony-4-updates/githut/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php(494): AppKernel->regi  
  sterBundles()                                                                                                                                     
  #1 /home/chris/Development/crv-symfony-4-updates/githut/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php(134): Symfony\Compone  
  nt\HttpKernel\Kernel->initializeBundles()                                                                                                         
  #2 /home/chris/Development/crv-symfony-4-updates/githut/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php(63): S  
  ymfony\Component\HttpKernel\Kernel->boot()                                                                                                        
  #3 /home/chris/Development/crv-symfony-4-updates/githut/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(148): Symfony\Bundl  
  e\FrameworkBundle\Console\Application->doRun(Ob in /home/chris/Development/crv-symfony-4-updates/githut/app/AppKernel.php on line 19              

update [--prefer-source] [--prefer-dist] [--dry-run] [--dev] [--no-dev] [--lock] [--no-custom-installers] [--no-autoloader] [--no-scripts] [--no-progress] [--no-suggest] [--with-dependencies] [-v|vv|vvv|--verbose] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--apcu-autoloader] [--ignore-platform-reqs] [--prefer-stable] [--prefer-lowest] [-i|--interactive] [--root-reqs] [--] [<packages>]...

Oh mercy.

Breaking Changes, Migraine Incoming

The error message is immediately scary, but also quite helpful:

PHP Fatal error:  Uncaught Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load class "GuzzleBundle" from namespace "EightPoints\Bundle\GuzzleBundle".

Ok, so a class cannot be found in the given namespace.

Which class?

Well, it may be obvious to you. It may not. If you're a beginner then I'm guessing not.

The next line reveals more info:

Did you forget a "use" statement for another namespace? in /home/chris/Development/crv-symfony-4-updates/githut/app/AppKernel.php:19
Stack trace:

Ahh, ok, let's look in AppKernel.php:

<?php

// app/AppKernel.php

use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = [
            new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
            new Symfony\Bundle\SecurityBundle\SecurityBundle(),
            new Symfony\Bundle\TwigBundle\TwigBundle(),
            new Symfony\Bundle\MonologBundle\MonologBundle(),
            new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
            new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
            new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),

            new EightPoints\Bundle\GuzzleBundle\GuzzleBundle(),

            new AppBundle\AppBundle(),
        ];

If you're using a decent IDE like PhpStorm then the problem line will be highlighted for you.

The error message did tell us that line 19 is the problematic line also.

new EightPoints\Bundle\GuzzleBundle\GuzzleBundle(),

This may look correct. However, with eightpoints/guzzle-bundle version 7 or higher, we must change this to:

new EightPoints\Bundle\GuzzleBundle\EightPointsGuzzleBundle()

This is documented.

<?php

// app/AppKernel.php

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = [
-            new EightPoints\Bundle\GuzzleBundle\GuzzleBundle(),
+            new EightPoints\Bundle\GuzzleBundle\EightPointsGuzzleBundle(),

Feeling satisfied and smug at this point, we could try a cache:clear to double check everything is behaving:

php bin/console cache:clear

In FileLoader.php line 168:

  There is no extension able to load the configuration for "guzzle" (in /home/chris/Development/crv-symfony-4-updates/githut/app/config/config.yml  
  ). Looked for namespace "guzzle", found "framework", "security", "twig", "monolog", "swiftmailer", "doctrine", "sensio_framework_extra", "eight_  
  points_guzzle", "debug", "web_profiler", "sensio_distribution", "web_server" in /home/chris/Development/crv-symfony-4-updates/githut/app/config/  
  config.yml (which is being imported from "/home/chris/Development/crv-symfony-4-updates/githut/app/config/config_dev.yml").                       

In YamlFileLoader.php line 701:

  There is no extension able to load the configuration for "guzzle" (in /home/chris/Development/crv-symfony-4-updates/githut/app/config/config.yml  
  ). Looked for namespace "guzzle", found "framework", "security", "twig", "monolog", "swiftmailer", "doctrine", "sensio_framework_extra", "eight_  
  points_guzzle", "debug", "web_profiler", "sensio_distribution", "web_server"                                                                      

Oh for the love of Mike.

Ok, more stuff to fix.

Again it's a good idea to look at the docs.

The new way of working is:

# app/config/config.yml

eight_points_guzzle:
    clients:
        api_payment:
            base_url: "http://api.domain.tld"

And here's what we have:

# app/config/config.yml

guzzle:
    clients:
        8p_guzzle_client:
            base_url: ""

Ok, so updating shouldn't be too difficult:

# app/config/config.yml

eight_points_guzzle:
    clients:
        8p_guzzle_client:
            base_url: ""

You may wish to change the client name also at this point. I'm not going too, as ours is fairly generic all the same.

Again, let's check with a cache:clear:

php bin/console cache:clear

In ContainerBuilder.php line 1018:

  You have requested a non-existent service "guzzle.client.8p_guzzle_client".  

Arghhh.

Well, if you remember from our previous changes we did add in:

# app/config/services.yml

services:

    # other stuff removed for brevity

    GuzzleHttp\Client: "@guzzle.client.8p_guzzle_client"

And now this needs updating:

# app/config/services.yml

services:

    GuzzleHttp\Client: "@eight_points_guzzle.client.8p_guzzle_client"

One last time on the cache:clear:

php bin/console cache:clear

 // Clearing the cache for the dev environment with debug true                                                          

 [OK] Cache for the "dev" environment (debug=true) was successfully cleared.                                            

Hoorah.

Now if you reload your GitHut website we have zero deprecations remaining.

Let that sink in for a moment. Then head to the kitchen and make yourself a celebratory beverage of your own choosing.

Code For This Video

Get the code for this video.

Episodes

# Title Duration
1 What happened to my Web Server? 04:09
2 Fixing Generic Symfony Deprecations 07:11
3 Fixing Deprecations In Our Own Code 08:52
4 Fixing Third Party Bundle Deprecations (Indirectly) 05:38
5 [Part 1/2] Migrating to Symfony 4.0 with Flex 06:44
6 [Part 2/2] Migrating to Symfony 4.0 with Flex 10:44