原文地址(http://php-di.org/doc/getting-start)
Getting started with PHP-DI
(开始使用PHP-DI)
Welcome! This guide will help you get started with using PHP-DI in your project.
Before beginning, you need to know what dependency injection is. If you don't, there's a whole article dedicated to it: Understanding dependency injection.
(欢迎光临!本指南将帮助您在项目中开始使用PHP-DI。
在开始之前,您需要知道依赖注入是什么。如果你还不了解它的含义,这里有一整篇文章专门介绍它:理解依赖注入)
Installation
(安装) Install PHP-DI with Composer: (使用composer安装PHP-DI)
代码语言:javascript复制composer require php-di/php-di
PHP-DI requires PHP 7.0 or above. (PHP-DI需要PHP 7.0或者更高)
Basic usage
(基本用法)
1. Use dependency injection
(使用依赖注入) First, let's write code using dependency injection without thinking about PHP-DI: (首先,让我们在不考虑PHP-DI的情况下使用依赖注入编写代码:)
代码语言:javascript复制class Mailer
{
public function mail($recipient, $content)
{
// send an email to the recipient
}
}
代码语言:javascript复制class UserManager
{
private $mailer;
public function __construct(Mailer $mailer)
{
$this->mailer = $mailer;
}
public function register($email, $password)
{
// The user just registered, we create his account
// ...
// We send him an email to say hello!
$this->mailer->mail($email, 'Hello and welcome!');
}
}
As we can see, the UserManager
takes the Mailer
as a constructor parameter: this is dependency injection!
(就像我们所看到的这样,“UserManager”将“Mailer”作为构造函数参数:这就是依赖项注入!)
2. Create the container
(创建容器) You can create a container instance pre-configured for development very easily: (您可以很容易地创建一个预先配置的容器实例:)
代码语言:javascript复制$container = new Container();
If you want to register definition files (explained in PHP definitions) or tweak some options, you can use the container builder: (如果您想注册定义文件(在PHP definitions中解释)或调整一些选项,您可以使用容器构建器:)
代码语言:javascript复制$builder = new DIContainerBuilder();
$builder->...
$container = $builder->build();
3. Create the objects
(创建对象) Without PHP-DI, we would have to "wire" the dependencies manually like this: (如果没有PHP-DI,我们将不得不像这样手动地“连接”依赖项:)
代码语言:javascript复制$mailer = new Mailer();
$userManager = new UserManager($mailer);
Instead, we can let PHP-DI figure out the dependencies: (相反,我们可以让PHP-DI计算出依赖项:)
代码语言:javascript复制$userManager = $container->get('UserManager');
Behind the scenes, PHP-DI will create both a Mailer object and a UserManager object. (在幕后,PHP-DI将创建一个Mailer对象和一个UserManager对象。)
How does it know what to inject? (它怎么知道我们要注入什么对象?)
The container uses a technique called autowiring. This is not unique to PHP-DI, but this is still awesome. It will scan the code and see what are the parameters needed in the constructors.
In our example, the UserManager
constructor takes a Mailer
object: PHP-DI knows that it needs to create one. Pretty basic, but very efficient.
(该容器使用一种称为autowiring自动连接的技术。
这并不是PHP-DI特有的,但这仍然是很棒的。
它将扫描代码并查看构造函数中需要的参数。
在我们的示例中,UserManager
构造函数接受一个Mailer
对象:PHP-DI知道它需要创建一个。
很基本,但很有效。)
Wait, isn't that weird and risky to scan PHP code like that? (等等,扫描PHP代码那不是很奇怪而且有风险的吗?)
Don't worry, PHP-DI uses PHP's Reflection classes which is pretty standard: Laravel, Zend Framework and many other containers do the same. Performance wise, such information is read once and then cached, it has no impact. (不要担心,PHP-DI使用了PHP的反射类 ,这是相当标准的:Laravel、Zend Framework和许多其他容器都是这样做的。性能方面,这些信息被读取一次,然后就会缓存起来,它没有任何影响。)
Defining injections
(定义注入) We have seen autowiring, which is when PHP-DI figures out automatically the dependencies a class needs. But we have 3 ways to define what to inject in a class: (我们已经看到了autowiring自动链接,即PHP-DI自动计算出类需要的依赖关系。但是我们有3种方法来定义在一个类中注入什么:)
- using autowiring
- using annotations
- using PHP definitions
- 使用 autowiring
- 使用 annotations
- 使用 PHP definitions Every one of them is different and optional. Here is an example of PHP definitions in a file: (每一个都是不同的和可选的。下面是一个文件中的PHP定义示例:)
return [
'api.url' => 'http://api.example.com',
'Webservice' => function (Container $c) {
return new Webservice($c->get('api.url'));
},
'Controller' => DIcreate()
->constructor(DIget('Webservice')),
];
Please read the Defining injections documentation to learn about autowiring, annotations and PHP definitions. (请阅读Defining injections的注入文档,了解autowiring, annotations and PHP definitions。)
Framework integration
(集成到框架中) We have seen in the example above that we can use the container to get objects: (我们在上面的例子中已经看到,我们可以使用容器来获取对象:)
代码语言:javascript复制$userManager = $container->get('UserManager');
However we don't want to call the container everywhere in our application: it would couple our code to the container. This is known as the service locator antipattern - or dependency fetching rather than injection. (但是,我们不希望在应用程序中到处调用容器:它会将我们的代码与容器耦合。这被称为服务定位器反模式或依赖抓取而不是注入。) To quote the Symfony documentation: (引用Symfony文档:)
You will need to get [an object] from the container at some point but this should be as few times as possible at the entry point to your application. 您需要从容器中获取(一个对象),但这应该是在您的应用程序的入口点上尽可能少的时间。
For this reason, PHP-DI integrates with some frameworks so that you don't have to call the container (dependencies are injected in controllers): (出于这个原因,PHP-DI集成了一些框架,这样您就不必调用容器(依赖项被注入控制器):)
- Symfony
- Slim
- Silex
- Zend Framework 2
- Silly
If you want to use PHP-DI with another framework or your own code, try to use $container->get()
in you root application class or front controller. Have a look at this demo application built around PHP-DI for a practical example.
(如果您希望使用另一个框架或您自己的代码使用PHP-DI,请尝试在您的根应用程序类或前端控制器中使用$container->get()。我们来看看这个围绕PHP-DI构建的演示应用程序。)
What's next
(接下来是什么) You can head over to the documentation index. You can also read the Best practices guide, it's a good way to get a good view on when to use each of PHP-DI's features. 你可以去查阅文档索引。您还可以阅读最佳实践指南,这是了解何时使用PHP-DI特性的好方法。 下面是一些你现在可能感兴趣的话题: Here are some other topics that might interest you right now: (下面是一些你现在可能感兴趣的话题:)
- Configuring the container
- Defining injections