翻译进度
3
分块数量
1
参与人数

7.3. Migration from PHP-DI 5.x to 6.0

这是一篇协同翻译的文章,你可以点击『我来翻译』按钮来参与翻译。


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
  • 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

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 () {
            ...
        })),
];

当然,这仅适用于配置文件中的闭包。

作用域

作用域已被删除,因为它们超出了容器的范围。 更清楚的是,prototype 作用域不能再使用了,singleton 作用域现在无处不在。

scopes 文档中阅读更多详细信息和替代方案。

缓存

缓存几乎完全被移除,取而代之的是一个更快的替代方案:编译容器(参见下面关于编译容器的部分)。

因此,ContainerBuilder::setDefinitionCache() 方法也被删除了。 在你的代码中可以删除该行(并编译容器)。 阅读 Performances 了解更多信息。

编译容器

PHP-DI,就像 Symfony 的容器,现在可以编译成非常优化的 PHP 代码。 这可以为生产环境提供最佳性能。 要编译容器,请阅读 Performances

内部变化

如果你要覆盖或扩展 PHP-DI 的某些内部类,请注意它们可能已更改。

郁雁 翻译于 2年前

本文章首发在 LearnKu.com 网站上。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

贡献者:1
讨论数量: 0
发起讨论 只看当前版本


暂无话题~