资讯专栏INFORMATION COLUMN

【译文】PHP-DI和依赖注入的最佳实践

ivydom / 2845人阅读

摘要:在构造函数中注入依赖性在中作为服务的控制器这是痛苦的,当你有个以上的依赖项,你的构造函数是行样板代码在属性中注入依赖性这是我们建议的解决方案。

PHP-DI是用PHP编写的、强大的和实用的、框架无关的依赖注入容器。这是一个关于如何使用PHP-DI和依赖注入的最佳实践指南。

文章来源于PHP-DI,作者:Matthieu Napoli和贡献者。PHP-DI是用PHP编写的、强大的和实用的、框架无关的依赖注入容器。

原文地址(英文):http://php-di.org/doc/best-pr...

PHP-DI在【本站实用开源目录】链接:http://www.worldlink.com.cn/o...
这是一个关于如何使用PHP-DI和依赖注入的最佳实践指南。

虽然它可能不包括每个案例,并满足每个人,但它可作为抛砖引玉,以帮助您开始依赖注入。

如果你不同意该指南中解释的任何内容,那没关系。你应该对这些问题提出自己的见解:)。它不会阻止你以你想要的方式使用PHP-DI。

使用容器和依赖注入的规则

以下是一些基本规则:

不要直接从容器中获取一个条目(总是使用依赖注入)
更普遍的是,编写代码解耦的容器
针对接口的类型约束,要在容器的配置中配置使用哪种实现
#编写控制器
在控制器中使用依赖注入通常是最痛苦的。

如果我们以Symfony 2为例(但这通常适用于每个框架),这里有你的选择:

在容器中注入控制器,并调用 $container->get(...)
这是不好的,见规则n°1。

在构造函数中注入依赖性(在Symfony中作为服务的控制器)
这是痛苦的,当你有5个以上的依赖项,你的构造函数是15行样板代码

在属性中注入依赖性
这是我们建议的解决方案。

例如:

class UserController
{
    /**
     * @Inject
     * @var FormFactoryInterface
     */
    private $formFactory;
    public function createForm($type, $data, $options)
    {
        // $this->formFactory->...
    }
}

如你所见,这个解决方案需要很少的代码,很容易理解和利于IDE支持(自动完成,重构,...)。

属性注入通常让人皱眉头,这是有一定的原因的:

注入私有属性破坏了封装
它不是一个显式的依赖:没有约定,说你的类需要设置属性以工作
如果使用PHP-DI的注解来标记要注入的依赖关系,那么您的类依赖于容器(请参见上面的第2条规则)

如果您遵循关于如何编写应用程序的一般最佳实践,您的控制器将不包含业务逻辑(仅对模型进行路由调用并绑定返回的值以查看)。

因此:

你不会对它进行单元测试(这并不意味着你不会在接口上写功能测试)
你不需要在别处重用它
如果你改变框架,你可能不得不重写它(或其部分)(因为大多数依赖,如请求、响应、模板系统等将改变)
此解决方案提供了许多优点,没有主要的缺点,因此我们建议在控制器中使用注解。

编写服务

给定一个服务旨在被重用、测试和独立于你的框架,我们不建议使用注解注入依赖。 相反,我们建议使用构造函数注入和自动装配:

class OrderService implements OrderServiceInterface
{
    private $paymentService;
    public function __construct(PaymentServiceInterface $paymentService)
    {
        $this->paymentService = $paymentService;
    }
    public function processOrder($order)
    {
        $this->paymentService->...
    }
}

通过使用自动装配(默认情况下启用),您自己保存绑定配置中的构造函数的每个参数。 PHP-DI将通过检查您的参数的类型来猜测它需要注入哪个对象。

在某些情况下,使用自动装配还不够,因为一些参数将是一个标量(string,int,...)。 此时,您需要明确定义要在该标量参数中注入的内容,为此,您可以:

定义方法/类的全部注入(即,每个参数)。
例如:

// ...
OrderService::class => DIobject()
    ->constructor(DIget(SomeOtherService::class), "a value"),

];
或者只定义标量参数,让PHP-DI使用自动装配。
例如:

 DIobject()
        ->constructorParameter("paramName", "a value"),
];

这个解决方案通常是优选的,避免重新定义一切。

旁注:如规则n°3中所述,我们建议对接口进行类型约束。 在这种情况下,您将需要将接口映射到容器在配置中应该使用的实现:

使用库

当使用库,如日志记录器,ORM,...有时需要配置它们。

在这种情况下,我们建议您在配置文件中定义这些依赖关系。 我们还建议在配置有点复杂时使用匿名函数。

匿名函数允许你编写真正的PHP代码,这是伟大的,因为你可以使用库的文档,得到IDE支持,作为一个PHP开发人员,你懂的:)。

这里是一个例子,Monolog,一个PHP记录器:

 DIfactory(function () {
        $logger = new Logger("mylog");
        $fileHandler = new StreamHandler("path/to/your.log", Logger::DEBUG);
        $fileHandler->setFormatter(new LineFormatter());
        $logger->pushHandler($fileHandler);
        return $logger;
    }),
];

当然,如你所见,我们使用PSR-3接口进行注入。 这样,我们可以随时用任何PSR-3记录器替换Monolog,只需更改此配置即可。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/31711.html

相关文章

  • PHP程序员如何理解依赖注入容器(dependency injection container)

    摘要:代码这就是控制反转模式。是变量有默认值则设置默认值是一个类,递归解析有默认值则返回默认值从容器中取得以上代码的原理参考官方文档反射,具有完整的反射,添加了对类接口函数方法和扩展进行反向工程的能力。 PHP程序员如何理解依赖注入容器(dependency injection container) 背景知识 传统的思路是应用程序用到一个Foo类,就会创建Foo类并调用Foo类的方法,假如这...

    Coding01 评论0 收藏0
  • 译文】NPM 小技巧&最佳实践

    摘要:但在生产环境下,如果不指定保存依赖的版本号会存在问题。它会生成一个文件,不仅记录了当前环境中使用的模块精确的版本号,还记录了这些模块的其他依赖的版本,以此类推。 本文来自国外新手向技术博客RisingStack。有兴趣的同学可点击原文查看。 相信npm install是npm-cli最常用的功能,但其实它还有很多其他可挖掘的地方。在本文中,你将会学习如何在应用开发的整个生命周期中——...

    0x584a 评论0 收藏0
  • 【译】深入研究Laravel依赖注入容器

    摘要:原文地址下面是中文翻译拥有强大的控制反转依赖注入容器。单例在使用自动绑定和时,每次需要时都会创建一个新的实例或者调用闭包。 原文地址 Laravels Dependency Injection Container in Depth 下面是中文翻译 Laravel拥有强大的控制反转(IoC)/依赖注入(DI) 容器。不幸的是官方文档并没有涵盖所有可用的功能,因此,我决定尝试写文档为自...

    chavesgu 评论0 收藏0
  • 【PhpBoot】 为快速开发 RESTful API 设计PHP框架

    摘要:是为快速开发设计的框架。特色框架提供许多主流的特性如依赖注入等。轻松支持是目前最流行的接口文档框架。在一开始就非常注重框架的友好性尽可能让框架保持准确的代码提示。 PhpBoot showImg(https://segmentfault.com/img/remote/1460000004864102);showImg(https://segmentfault.com/img/remot...

    mist14 评论0 收藏0
  • [译]Express在生产环境下最佳实践 - 安全性

    摘要:前言这将是一个分为两部分,内容是关于在生产环境下,跑应用的最佳实践。潜在的攻击者可以通过它们进行针对性的攻击。 前言 这将是一个分为两部分,内容是关于在生产环境下,跑Express应用的最佳实践。第一部分会关注安全性,第二部分最会关注性能和可靠性。当你读这篇文章时,假设你已经对Node.js和web开发有所了解,并且对生产环境有了概念。 概览 生产环境,指的是软件生命循环中的某个阶段。...

    Forelax 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<