PHPackages                             phoole/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. phoole/di

ActiveLibrary

phoole/di
=========

Slim, powerful and full compatible PSR-11 dependency injection library for PHP

1.1.0(6y ago)4181Apache-2.0PHPPHP &gt;=7.2.0

Since Oct 11Pushed 6y ago1 watchersCompare

[ Source](https://github.com/phoole/di)[ Packagist](https://packagist.org/packages/phoole/di)[ RSS](/packages/phoole-di/feed)WikiDiscussions master Synced 2mo ago

READMEChangelog (8)Dependencies (3)Versions (9)Used By (0)

di
==

[](#di)

[![Build Status](https://camo.githubusercontent.com/44f47ec5d19a1123b7c00a27e8ce0b3fed139ad32ad74890450f020cd29c543f/68747470733a2f2f7472617669732d63692e636f6d2f70686f6f6c652f64692e7376673f6272616e63683d6d6173746572)](https://travis-ci.com/phoole/di)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/21c7014734670c4bf7a0a5309d582d01c784b4f7304025846bf92549af484402/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f70686f6f6c652f64692f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/phoole/di/?branch=master)[![Code Climate](https://camo.githubusercontent.com/a98e744cfc07912f4f10e5dde9d9d536fdaead35adf3810f8bbc412592b80d30/68747470733a2f2f636f6465636c696d6174652e636f6d2f6769746875622f70686f6f6c652f64692f6261646765732f6770612e737667)](https://codeclimate.com/github/phoole/di)[![PHP 7](https://camo.githubusercontent.com/b218debc86b43188dcbff0069408c824cecd76dacf9f85d144d90318c7e02e9a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f70686f6f6c652f6469)](https://packagist.org/packages/phoole/di)[![Latest Stable Version](https://camo.githubusercontent.com/cd2b114d4a880d36d3974d64766638c3631efe94029bb531382c180e6cc97467/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f70686f6f6c652f6469)](https://packagist.org/packages/phoole/di)![License](https://camo.githubusercontent.com/5df6b68f1d3b3ab71eeb3b76242c3c499d15e08c4343fabc51363bcedc1e2ad4/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f70686f6f6c652f6469)

Slim, powerful and full compatible [PSR-11](http://www.php-fig.org/psr/psr-11/ "Container Interface") dependency injection library for PHP.

It builds upon the versatile [phoole/config](https://github.com/phoole/config "phoole/config") library and supports [object decorating](#decorate), [object scope](#scope) and more. It requires PHP 7.2+. It is compliant with [PSR-1](http://www.php-fig.org/psr/psr-1/ "PSR-1: Basic Coding Standard"), [PSR-4](http://www.php-fig.org/psr/psr-4/ "PSR-4: Autoloader"), [PSR-11](http://www.php-fig.org/psr/psr-11/ "Container Interface") and [PSR-12](http://www.php-fig.org/psr/psr-12/ "Extended Coding Style Guide").

Installation
------------

[](#installation)

Install via the `composer` utility.

```
composer require "phoole/di"

```

or add the following lines to your `composer.json`

```
{
    "require": {
       "phoole/di": "1.*"
    }
}
```

Usage
-----

[](#usage)

- With configuration from files or definition array

    ```
    use Phoole\Di\Container;
    use Phoole\Config\Config;
    use Phoole\Cache\Cache;
    use Phoole\Cache\Adaptor\FileAdaptor;

    $configData = [
        // service definitions
        'di.service' => [
            // classname & constructor arguments
            'cache'  => [
                'class' => Cache::class,
                'args' => ['${#cacheDriver}'] // optional
            ],

            // use classname directly
            'cacheDriver' => FileAdaptor::class
        ],

        // methods to run after each object initiation
        'di.after' => [
            // a callable, takes THE object as parameter
            function($obj) { echo "ok"; },

            // will be converted to $obj->setLogger($logger)
            'setLogger',
        ]
    ];

    // inject configurations into container
    $container = new Container(new Config($configData));

    // get service by id 'cache' (di.service.cache)
    $cache = $container->get('cache');
    ```

    Container related configurations are under the node `di` and service definitions are under the `di.service` node.

Features
--------

[](#features)

- **References**

    References in the form of '${reference}' can be used to refer to predefined parameters from the config or services in the container.

    **Characters of `'$', '{', '}', '.'` are not allowed in reference name**. Characters of `'#', '@'` have special meanings, such that should not be part of *normal* service names.

    - Parameter references like `${system.tempdir}`

        ```
        $config = [
            ...
            // use predefined 'sytem.tmpdir' in arguments etc.
            'di.service.cacheDriver' => [
                'class' => FileAdaptor::class,
                'args'  => ['${system.tmpdir}'],
            ],
            ...
        ];
        ```

        See [phoole/config reference](https://github.com/phoole/config#ref) for detail. Parameter references are read from configuration files or array.
    - Service references like `${#cache}`

        Service object reference in the form of `${#serviceId}` can be used to referring a service instance in the container.

        ```
        $configData = [
          ...
          'di.service' => [
              'cache'  => [
                  'class' => Cache::class,
                  'args' => ['${#cacheDriver}'] // object reference
              ],
              'cacheDriver' => ...
          ...
        ```

        Two reserved service references are **`${#container}`** and **`${#config}`**. These two are referring the container instance itself and the config instance it is using. These two can be used just like other service references.
    - Using references

        References can be used anywhere in the configuration.

        ```
        $confData = [
            // methods executed after ALL object initiation
            'di.after' => [
                [['${#logger}', 'notice'], ['object created using ${log.facility}']]
            ]
        ];
        ```
- **Object decorating**

    *Object decorating* is to apply decorating changes (executing methods etc.) right before or after the instantiation of a service instance.

    - Decorating methods for **individual instance** only

        ```
        $config = [
           'di.service' => [
               ...
               'cache', [
                   'class'  => '${cache.class}',
                   'args'   => ['${#cachedriver}'], // constructor arguments
                   'before' => [
                       [['${#logger}', 'info'], ['before initiating cache']], // $logger->info(...)
                   ],
                   'after'  => [
                       'clearCache', // $cache->clearCache() method
                       ['setLogger', ['${#logger}']], // $cache->setLogger($logger), argument is optional
                       [['${#logger}', 'info'], ['just a info']], // $logger->info(...)
                       function($cache) { // a callable takes object in parameter

                       },
                   ]
               ],
               ...
           ]
        ];
        ```

        By adding `before` or `after` section into the `cache` service definition in the form of `[callableOrMethodName, OptionalArgumentArray]`, these methods will be executed right before/after `cache` instantiation.

        `callableOrMethodName` here can be,

        - method name of initiated object

            ```
            ...
              'after' => [
                  // $obj->setLogger($logger), $logger will be injected automatically
                  'setLogger', // object implementing 'LoggerAwareInterface'
              ],
            ...
            ```
        - a valid callable which takes initiated object as parameter

            ```
             ...
               'after' => [
                   // callable takes initiated object as parameter
                   function($obj) {
                   },
               ],
             ...
            ```
        - a pseudo callable with references (after resolving the references, it is a valid callable).

            ```
             ...
               'after' => [
                   // a pseudo callable with references
                   [['${#logger}', 'info'], ['just a info']], // $logger->info(...)
               ],
             ...
            ```

        `OptionalArgumentArray` here can be,

        - empty
        - array of values or references
    - Common decorating methods for **all instances**

        ```
        $configData = [
            // before all instances initiated
            'di.before' => [
                [['${#logger}', 'info'], ['before create']],
            ],
            // after methods for all instances
            'di.after' => [
                ['setLogger', ['${#logger}']], // arguments are optional
                'setDispatcher',  // simple enough, set event dispatcher
            ],
        ];
        ```

        Common methods can be configured in the 'di.before' or 'di.after' node to apply to all the instances right before or after their instantiation.
- **Object scope**

    - Shared objects and new objects

        By default, service instances in the container are shared inside the container. If users want different instance each time, they may just append **'@'** to the service id.

        ```
        // cache service by default is in shared scope
        $cache1 = $container->get('cache');

        // get again
        $cache2 = $container->get('cache');

        // same
        var_dump($cache1 === $cache2); // true

        // get a NEW cache instance
        $cache3 = $container->get('cache@');

        // different instances
        var_dump($cache1 !== $cache3); // true

        // but both share the same cacheDriver dependent service
        var_dump($cache1->getAdaptor() === $cache3->getAdaptor()); // true
        ```
    - Object scope

        You may get an instance in your **own scope** as follows

        ```
        // no scope
        $cache1 = $container->get('cache');

        // in `myScope`
        $cache2 = $container->get('cache@myScope');

        // different instances
        var_dump($cache1 !== $cache2); // true

        // shared in myScope
        $cache3 = $container->get('cache@myScope');
        var_dump($cache2 === $cache2); // true
        ```

        Service references can also have scope defined as follows,

        ```
        $container->set('cache', [
            'class' => Cache::class,
            'args'  => ['${#driver@myScope}'] // use driver of myScope
        ]);
        ```
- **Static access**

    - Access predefined services statically

        Services in the container can also be access through a static way. But `get`and `has` are reserved.

        ```
        // after container initiated
        $container = new Container(new Config(...));

        // equals to $cache = $container->get('cache')
        $cache = Container::cache();

        // if myservice defined and invokable
        $obj = Container::myservice('test');
        ```
    - Initiating object by taking advantage of dependency injection

        ```
        use Phoole\Cache\Cache;
        use Psr\Log\LoggerAwareTrait;
        use Psr\Log\LoggerAwareInterface;

        class MyClass implements LoggerAwareInterface
        {
             use LoggerAwareTrait;

             public function __construct(Cache $cache)
             {
             }
        }

        // $cache will be injected automatically
        $obj = Container::create(MyClass::class);

        // also 'setLogger' will be executed if defined in 'di.after' section
        $logger = $obj->getLogger();
        ```
- **Autowiring** and **auto injection**

    - Parameter autowiring (resolving)

        Parameters of a constructor/callable will be resolved by looking

        - exists in the classmap (service objects created already) ?
        - classname known to the script (class defined already) ?
    - Auto injection

        Instead of using **'annotation'**, we encourage of using `*AwareInterface`for your own classes' dependency injection.

        ```
        use Psr\Log\LoggerAwareTrait;
        use Psr\Log\LoggerAwareInterface;

        class MyOwnClass implements LoggerAwareInterface
        {
             use LoggerAwareTrait;
             ...
        }

        // create your object with arguments
        $obj = Container::create(MyOnwClass::class, [...]);

        // $logger injected by the container automatically
        $logger = $obj->getLogger();
        ```

        `Container` has all the common injection predefined in the `di.after` section

        ```
        $config = [

            'di.after' => [
                'setLogger',        // logger aware
                'setCache',         // cache aware
                'setDispatcher',    // event aware
                'setContainer',     // container aware
                ...
            ],
        ];
        ...
        ```
- **`ContainerAWareInterface`**

    Both `ContainerAWareInterface` and `ContainerAWareTrait` available.

APIs
----

[](#apis)

- Container related

    - `get(string $id): object` from *ContainerInterface*
    - `has(string $id): bool` from *ContainerInterface*

        `$id` may have `@` or `@scope` appended.

Testing
-------

[](#testing)

```
$ composer test
```

Dependencies
------------

[](#dependencies)

- PHP &gt;= 7.2.0
- phoole/config &gt;= 1.\*

License
-------

[](#license)

- [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0)

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity11

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 94.7% 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 ~5 days

Total

8

Last Release

2364d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/3bae7d5f135e90fd05271574bfd04d4844169bd4c554eaa9e103e4af69267ffc?d=identicon)[phoole](/maintainers/phoole)

---

Top Contributors

[![phossa](https://avatars.githubusercontent.com/u/8499165?v=4)](https://github.com/phossa "phossa (18 commits)")[![phoole](https://avatars.githubusercontent.com/u/55728163?v=4)](https://github.com/phoole "phoole (1 commits)")

---

Tags

containerdependency-injectiondiphoolephppsr-11swoolephpdependency-injectionlibrarydiphoole

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

PHPackages © 2026

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