PHPackages                             soliphp/di - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [PSR &amp; Standards](/categories/psr-standards)
4. /
5. soliphp/di

ActiveLibrary[PSR &amp; Standards](/categories/psr-standards)

soliphp/di
==========

Soli Dependency Injection Container

v2.0.2(7y ago)1131232MITPHPPHP &gt;=5.6.0

Since Mar 22Pushed 1y ago2 watchersCompare

[ Source](https://github.com/soliphp/di)[ Packagist](https://packagist.org/packages/soliphp/di)[ Docs](https://github.com/soliphp/di)[ RSS](/packages/soliphp-di/feed)WikiDiscussions master Synced 4w ago

READMEChangelog (9)Dependencies (1)Versions (11)Used By (2)

Soli Dependency Injection Container
-----------------------------------

[](#soli-dependency-injection-container)

当前项目参考了 Phalcon 框架的[依赖注入与服务定位器](https://docs.phalconphp.com/en/latest/di) 和 Laravel 框架的[服务容器](https://laravel.com/docs/master/container) 实现。

服务容器的目的为了降低代码的耦合度，提高应用的可维护性；是用于管理类依赖和执行依赖注入的工具。

[![Build Status](https://camo.githubusercontent.com/132b997aa3010f7cd21e44e3578623a644cc21544d012c8735f9d8a068fe55da/68747470733a2f2f7472617669732d63692e6f72672f736f6c697068702f64692e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/soliphp/di)[![Coverage Status](https://camo.githubusercontent.com/2ce1deb599bdaafdc87e1f881c806227a3f3836b85ab147decdeb218585f944a/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f736f6c697068702f64692f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/soliphp/di?branch=master)[![License](https://camo.githubusercontent.com/2ad673600b5362ace2322954e9a07ffc9d80118327168137120390d71120e221/68747470733a2f2f706f7365722e707567782e6f72672f736f6c697068702f64692f6c6963656e7365)](https://packagist.org/packages/soliphp/di)

Table of Contents
-----------------

[](#table-of-contents)

- [安装](#%E5%AE%89%E8%A3%85)
- [先看一个简单的例子](#%E5%85%88%E7%9C%8B%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E4%BE%8B%E5%AD%90)
- [注册服务](#%E6%B3%A8%E5%86%8C%E6%9C%8D%E5%8A%A1)
    - [类名](#%E7%B1%BB%E5%90%8D)
    - [类实例](#%E7%B1%BB%E5%AE%9E%E4%BE%8B)
    - [闭包/匿名函数](#%E9%97%AD%E5%8C%85%E5%8C%BF%E5%90%8D%E5%87%BD%E6%95%B0)
        - [使用 $this 访问容器中的其他服务](#%E4%BD%BF%E7%94%A8-this-%E8%AE%BF%E9%97%AE%E5%AE%B9%E5%99%A8%E4%B8%AD%E7%9A%84%E5%85%B6%E4%BB%96%E6%9C%8D%E5%8A%A1)
    - [注册接口到实现](#%E6%B3%A8%E5%86%8C%E6%8E%A5%E5%8F%A3%E5%88%B0%E5%AE%9E%E7%8E%B0)
    - [共享（单例）服务](#%E5%85%B1%E4%BA%AB%E5%8D%95%E4%BE%8B%E6%9C%8D%E5%8A%A1)
- [获取服务](#%E8%8E%B7%E5%8F%96%E6%9C%8D%E5%8A%A1)
    - [get() 服务ID](#get-%E6%9C%8D%E5%8A%A1id)
    - [get() 类名](#get-%E7%B1%BB%E5%90%8D)
    - [对象属性](#%E5%AF%B9%E8%B1%A1%E5%B1%9E%E6%80%A7)
    - [数组下标](#%E6%95%B0%E7%BB%84%E4%B8%8B%E6%A0%87)
    - [$this](#this)
- [静态方式访问容器](#%E9%9D%99%E6%80%81%E6%96%B9%E5%BC%8F%E8%AE%BF%E9%97%AE%E5%AE%B9%E5%99%A8)
- [容器感知](#%E5%AE%B9%E5%99%A8%E6%84%9F%E7%9F%A5)
- [别名](#%E5%88%AB%E5%90%8D)
    - [为已注册服务定义别名](#%E4%B8%BA%E5%B7%B2%E6%B3%A8%E5%86%8C%E6%9C%8D%E5%8A%A1%E5%AE%9A%E4%B9%89%E5%88%AB%E5%90%8D)
    - [为类名定义别名](#%E4%B8%BA%E7%B1%BB%E5%90%8D%E5%AE%9A%E4%B9%89%E5%88%AB%E5%90%8D)
- [示例](#%E7%A4%BA%E4%BE%8B)
- [API 参考](#api-%E5%8F%82%E8%80%83)
- [测试](#%E6%B5%8B%E8%AF%95)
- [License](#license)

安装
--

[](#安装)

使用 `composer` 进行安装：

```
composer require soliphp/di

```

先看一个简单的例子
---------

[](#先看一个简单的例子)

```
use Psr\Log\LoggerInterface;

class ExceptionHandler
{
    /**
     * 日志记录器
     *
     * @var \Psr\Log\LoggerInterface
     */
    protected $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    /**
     * 异常报告
     */
    public function report(\Throwable $e)
    {
        $this->logger->error($e->getMessage());
    }
}

```

异常处理类 `ExceptionHandler` 需要 `logger` 记录（报告）异常， 因此，我们需要`注入`实现了 `Psr\Log\LoggerInterface` 接口的类。 而 `logger` 的实现是要发短信、发邮件或进日志系统，这个 `ExceptionHandler`是不关心的，所以我们可以轻易地将 `logger` 切换为另一个实现。 在为应用编写测试时，也可以轻松的模拟 `Psr\Log\LoggerInterface` 的实现。

注册服务
----

[](#注册服务)

服务的注册阶段，仅仅是存储服务定义的格式，并不会调用服务的定义； 而在获取服务（即使用服务）时，对服务定义进行调用，得到服务定义的执行结果。 这样便实现了对`服务的延迟加载`，避免实例化请求中未用到的服务。

以下 `$container` 变量均为 `Soli\Di\Container` 实例。

### 类名

[](#类名)

```
use Soli\Di\Container;

$container = new Container();

$container->set('someService', \SomeNamespace\SomeService::class);

```

### 类实例

[](#类实例)

```
$container->set('someService', new \SomeNamespace\SomeService());

```

### 闭包/匿名函数

[](#闭包匿名函数)

```
// 注册服务，存储服务的定义
$container->set('someService', function () {
    return new SomeService();
});

```

#### 使用 $this 访问容器中的其他服务

[](#使用-this-访问容器中的其他服务)

当使用匿名函数注册服务时，函数体内可以使用 `$this` 表示当前的 `$container` 容器类实例， 直接访问容器中的其他服务，便于服务之间进行交互。

```
// 注册服务，存储服务的定义
$container->set('someService', function () {
    // 此处的 $tihs 即是当前的 $container 容器类实例
    // 通过 $this 直接访问容器中的其他服务
    var_dump($this->otherService);
});

```

### 注册接口到实现

[](#注册接口到实现)

`注册接口到实现类`：

```
$container->set('Database\AdapterInterface', 'Database\Adapter\Mysql');

```

如果一个类需要处理后才会得到一个适用的实例，那么这里的实现就是一个匿名函数， 可以`注册接口到匿名函数`，注意匿名函数的返回实例即可：

```
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$container->set('Psr\Log\LoggerInterface', function () {
    // create a log channel
    $log = new Logger('name');
    $log->pushHandler(new StreamHandler('/path/to/your.log', Logger::WARNING));

    return $log;
});

```

### 共享（单例）服务

[](#共享单例服务)

共享服务意味着让服务以单例模式运行，之后的每次请求都会从容器取到同一个实例。 否则每次都会执行服务解析，返回新的服务实例。

`默认使用 set() 注册的服务都为共享服务`。

如果需要`每次都使用新的实例`，则需要将第三个参数 `$shared 设置为 false`。

```
$container->set('newInstance', 'SomeNamespace\SomeService', false);

```

获取服务
----

[](#获取服务)

获取服务时，调用服务定义，返回服务实例。

获取服务有多种方法：

### get() 服务ID

[](#get-服务id)

服务ID或者叫服务名称，使用 `get()` 方法获取已注册`服务ID`提供的服务：

```
$service = $container->get('someService');

```

### get() 类名

[](#get-类名)

对于`类名`无论是否已注册为服务，都可以直接通过容器的 `get()` 方法获取到它的单例：

```
$service = $container->get('SomeNamespace\UnregisteredClass');

```

这对于我们日常开发中经常用到的单例模式，将格外的方便。

如果某些类的依赖项不能通过容器去解析，可以通过将它们作为关联数组传递到 `get()` 方法的第二个参数注入它们。

```
$service = $container->get('SomeNamespace\UnregisteredClass', ['id' => 1]);

```

### 对象属性

[](#对象属性)

使用访问`对象属性`的方式，获取服务：

```
$service = $container->someService;

```

### 数组下标

[](#数组下标)

使用访问`数组下标`的方式，获取服务：

```
$service = $container['someService'];

```

### $this

[](#this)

匿名函数注册服务时[使用 $this 访问容器中的其他服务](#%E4%BD%BF%E7%94%A8-this-%E8%AE%BF%E9%97%AE%E5%AE%B9%E5%99%A8%E4%B8%AD%E7%9A%84%E5%85%B6%E4%BB%96%E6%9C%8D%E5%8A%A1)。

静态方式访问容器
--------

[](#静态方式访问容器)

```
$container = Container::instance();

$container->get('someService');

```

这里需要注意一下，在调用 `Container::instance()` 之前，一定已经执行过 `new Container()` 实例化操作。

容器感知
----

[](#容器感知)

如果某个服务实现了 `Soli\Di\ContainerAwareInterface` 容器感知接口， 在获取服务时，会自动调用 `setContainer()` 为其设置容器实例。

别名
--

[](#别名)

别名是用来给服务起不同的名字，以便可以使用不同的名字获取同一个服务。

注意不要定义与服务名称相同的别名。

### 为已注册服务定义别名

[](#为已注册服务定义别名)

首先注册以 `container` 为名称的服务：

```
$container->set('container', $container);

```

为 `container` 服务定义三个别名 `Soli\Di\Container`, `Soli\Di\ContainerInterface`, `Psr\Container\ContainerInterface`：

```
$container->alias('Soli\Di\Container', 'container');
$container->alias('Soli\Di\ContainerInterface', 'container');
$container->alias('Psr\Container\ContainerInterface', 'container');

```

如果容器中其他服务的构造函数使用了以上三个别名的「类型提示」，则会为其「自动注入」对应服务实例。

```
use Psr\Container\ContainerInterface;

class Component
{
    protected $container;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }
}

// 将自动注入 $container 参数
$component = $container->get(Component::class);

```

### 为类名定义别名

[](#为类名定义别名)

由于类名可直接通过容器获取其实例，所以类名是无需定义的服务名称。

那么我们便可以直接为类名定义别名：

```
$container->alias('Soli\Di\ContainerInterface', 'Soli\Di\Container');
$container->alias('Psr\Container\ContainerInterface', 'Soli\Di\Container');

```

示例
--

[](#示例)

在 [examples](examples) 文件夹下提供了一个类似 [Laravel 框架的服务提供者](https://laravel.com/docs/5.4/providers)的例子，感兴趣的同学可以前去翻看。

运行方法：

```
$ cd /path/to/soliphp/di/
$ composer install
$ php examples/index.php

```

API 参考
------

[](#api-参考)

[API 参考](http://api.soliphp.com/Soli/Di.html)

测试
--

[](#测试)

```
$ cd /path/to/soliphp/di/
$ composer install
$ phpunit

```

License
-------

[](#license)

MIT Public License

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance34

Infrequent updates — may be unmaintained

Popularity20

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~73 days

Recently: every ~104 days

Total

9

Last Release

2799d ago

Major Versions

v1.2.3 → v2.0.02018-05-22

PHP version history (2 changes)v1.0.0PHP &gt;=5.5.0

v2.0.0PHP &gt;=5.6.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/318253?v=4)[ueaner](/maintainers/ueaner)[@ueaner](https://github.com/ueaner)

---

Top Contributors

[![ueaner](https://avatars.githubusercontent.com/u/318253?v=4)](https://github.com/ueaner "ueaner (70 commits)")

---

Tags

containerdependencyinjectiondiphppsr-11solisoliphpcontainerdidependencyinjectionsoliphp

### Embed Badge

![Health badge](/badges/soliphp-di/health.svg)

```
[![Health](https://phpackages.com/badges/soliphp-di/health.svg)](https://phpackages.com/packages/soliphp-di)
```

###  Alternatives

[league/container

A fast and intuitive dependency injection container.

86894.4M429](/packages/league-container)[php-di/php-di

The dependency injection container for humans

2.9k55.5M1.2k](/packages/php-di-php-di)[aura/di

A serializable dependency injection container with constructor and setter injection, interface and trait awareness, configuration inheritance, and much more.

352982.2k60](/packages/aura-di)[league/tactician-container

Tactician integration for any container implementing PSR-11

7710.4M24](/packages/league-tactician-container)[mrclay/props-dic

Props is a simple DI container that allows retrieving values via custom property and method names

3512.7M3](/packages/mrclay-props-dic)[slince/di

A flexible dependency injection container

20272.1k6](/packages/slince-di)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
