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 disabled autowiring:
- replace it with
DI\create()
and everything should work
- replace it with
- if you use autowiring:
- replace it with
DI\create()
for definitions that replace autowiring completely (i.e. those that redefine all the parameters) - replace it with
DI\autowire()
for definitions that just define some parameters and let autowiring guess the rest of the parameters
- replace it with
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.
DI\link()
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.