Migrating from PHP-DI 5.x to 6.0

PHP-DI 6.0 is a new major version that comes with backward compatibility breaks.

This guide will help you migrate from a 5.x version to 6.0. It will only explain backward compatibility breaks, it will not present the new features (read the release notes or the blog post for that).

PHP version

PHP-DI requires PHP 7 or greater, it is no longer compatible with PHP 5.

As a consequence if you require ocramius/proxy-manager in your project (to benefit from lazy injection), you must require v2.0 (not 1.0, which is not compatible with PHP 7).

Container-Interop and PSR-11

PHP-DI 6 is compliant with PSR-11. Container-interop support has been dropped since container-interop has been replaced by PSR-11.

Most frameworks are now compatible with PSR-11 in their latest versions so there should be no migration step required on that side.

However it is possible you use the Interop\Container\ContainerInterface type-hint in your codebase. In that case, simply replace:

Interop\Container\ContainerInterface

with

Psr\Container\ContainerInterface

This might be the case for example in your PHP-DI configuration when using factories:

<?php

use Interop\Container\ContainerInterface;

return [
    'foo' => function (ContainerInterface $container) {
        return new Foo($container->get('bar'));
    },
    // ...
];

Replace use Interop\Container\ContainerInterface; with use Psr\Container\ContainerInterface; and you should be good to go.

Definitions

DI\object()

The DI\object() function helper has been removed. You should use DI\create() or DI\autowire() instead.

What should you do with your DI\object() definitions:

If you have a single configuration file, that's it.

If you have multiple configuration files, for example if you have built a module system, then there is one thing to be aware of: DI\object() used to extend previous definitions. create() and autowire() do not extend previous definitions, they completely override them, and this is intended. The behavior of object() was confusing and hard to understand, the new helpers are more predictable and simple.

If you want a "quick and dirty" upgrade you can also alias the create function using use function DI\create as object; at the top of your configuration file.

The DI\link() function helper was deprecated in 5.0. It is now completely removed. Use DI\get() instead.

Nested definitions and closures

Configuration files are now much more consistent: all definitions can be nested inside each other. You can nest create() definitions in arrays, get() in env(), etc.

Related to that, closures are now always interpreted as "factory" definitions, even if they are nested in another definition. For example:

return [
    'db.name' => env('DB_NAME', function ($container) {
        // Computes a default value if the environment variable doesn't exist
        return $container->get('db.prefix') . '_foo';
    }),

    // is the same as:
    'db.name' => env('DB_NAME', factory(function ($container) {
        // Computes a default value if the environment variable doesn't exist
        return $container->get('db.prefix') . '_foo';
    })),
];

If you used anonymous functions for something else than factories in your configuration, you need to wrap them in the DI\value() helper:

return [
    'router' => create(Router::class)
        ->method('setErrorHandler', value(function () {
            ...
        })),
];

Of course this applies only to closures that are inside your configuration files.

Scopes

Scopes have been removed as they are out of the scope of a container. To be more clear, the prototype scope cannot be used anymore, the singleton scope is now used everywhere.

Read more details and alternatives in the scopes documentation.

Caching

Caching has been almost entirely removed in favor of a much faster alternative: compiling the container (see the section about compiling the container below).

As such, the ContainerBuilder::setDefinitionCache() method was removed. In your code you can remove that line (and compile the container instead). Read the "performances" guide for more information.

Compiling the container

PHP-DI, like Symfony's container for example, can now be compiled to very optimized PHP code. That allows optimum performances for production environment. To compile the container read the "performances" guide.

Internal changes

If you were overriding or extending some internal classes of PHP-DI, be aware that they may have changed.