PHPackages                             vanilla/garden-container - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. vanilla/garden-container

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

vanilla/garden-container
========================

A dependency injection container.

v4.2.0(1y ago)2171.9k↓25.6%24MITPHPPHP &gt;=7.4CI passing

Since Nov 11Pushed 1y ago13 watchersCompare

[ Source](https://github.com/vanilla/garden-container)[ Packagist](https://packagist.org/packages/vanilla/garden-container)[ RSS](/packages/vanilla-garden-container/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (3)Versions (51)Used By (4)

Garden Container
================

[](#garden-container)

[![Build Status](https://camo.githubusercontent.com/f1d14b94b5f70db9083fd989050bd1779425d5400827f6b8ff6e138cc01da167/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f76616e696c6c612f67617264656e2d636f6e7461696e65722e7376673f7374796c653d666c6174)](https://travis-ci.com/vanilla/garden-container)[![Coverage](https://camo.githubusercontent.com/77eee08e122e768130d2f0f36466c11fedb3677193e6df811cb40fba2bba07d6/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f636f7665726167652f672f76616e696c6c612f67617264656e2d636f6e7461696e65722e7376673f7374796c653d666c6174)](https://scrutinizer-ci.com/g/vanilla/garden-container/)[![Packagist Version](https://camo.githubusercontent.com/8c4fb9af66e37c809ef6067ee038ebe03caff310a10a802b56590e27146cb9f2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f76616e696c6c612f67617264656e2d636f6e7461696e65722e7376673f7374796c653d666c6174)](https://packagist.org/packages/vanilla/garden-container)[![MIT License](https://camo.githubusercontent.com/ca6b60ac85385130b14c06ad45054d1a90d1079417ec7e3aaf0f2a61d793a8bc/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f76616e696c6c612f67617264656e2d636f6e7461696e65722e7376673f7374796c653d666c6174)](https://camo.githubusercontent.com/ca6b60ac85385130b14c06ad45054d1a90d1079417ec7e3aaf0f2a61d793a8bc/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f76616e696c6c612f67617264656e2d636f6e7461696e65722e7376673f7374796c653d666c6174)[![CLA](https://camo.githubusercontent.com/5b5a9f0ce123c668e8c2ae4deee7cd5d5c61b34cf47dcc402e397cea26bf5807/68747470733a2f2f636c612d617373697374616e742e696f2f726561646d652f62616467652f76616e696c6c612f67617264656e2d636f6e7461696e6572)](https://cla-assistant.io/vanilla/garden-container)

The Garden Container is a simple, but powerful dependency injection container.

Features
--------

[](#features)

- Automatically wire dependencies using parameter type hints. You get a lot of functionality before you've done any configuration.
- Create shared instances of objects without having to use difficult to test statics.
- Dependencies can be configured for base classes and interfaces and shared amongst subclasses.
- Setter injection can be configured for classes in the container.
- Dependencies can be configured to reference sub-containers. Use the container to inject properties from your config files.
- You can change the classes that implement dependencies or specify the definitive class for an interface.
- Objects can be constructed with custom factory functions to handle refactoring or edge-cases.

The Basics of Dependency Injection
----------------------------------

[](#the-basics-of-dependency-injection)

Consider the following simple object structure where a controller object depends on a Model object and that Model object depends on a database connection.

```
class Controller
{
    public function __construct(Model $model)
    {
    }
}

class Model
{
    public function __construct(PDO $db)
    {
    }
}
```

In order to use the controller you'd have to do a fair amount of construction.

```
$controller = new Controller(new Model(new PDO($dsn, $username, $password);
```

You can see how this can get messy when you have to create a lot objects or deep object hierarchies. With a dependency injection container you don't have to do any of that.

```
$dic = new Container();
$controller = $dic->get("Controller"); // dependencies magically wired up
```

The container inspects the objects its constructing for type hints and will then construct those objects by recursing back into the container. This is called **auto-wiring** and allows you to create any number of complex object graphs in a very simple manner. If you want to later add more dependencies then you can just add a parameter to your constructor and it will be resolved automatically.

A well designed application will rely heavily on auto-wiring and configure the container only for a few dependencies.

Configuring the Container with Rules
------------------------------------

[](#configuring-the-container-with-rules)

You can override the behaviour of any class's instantiation using rules. To configure a rule for a class you use the `rule()` method to select the rule and then any of the various rule getters and setters.

### Namespaces

[](#namespaces)

Rules are usually named with the name of the class that you will want to get from the container. If you are using namespaces then rules must be named with the fully qualified name of the class. The name can start with a forward slash, but it will be stripped before being processed.

PHP 5.6 introduced the `::class` construct which is a useful way to specify class names for the container.

### Case-Sensitivity

[](#case-sensitivity)

The container should be thought of as case-sensitive, however if you try and fetch a class with incorrect casing then the container will be able to find the class if the class is already included or the autoloader is case-insensitive. Since most PSR autoloaders are case-sensitive you are risking bugs if you are sloppy with casing in the container.

Constructor Args
----------------

[](#constructor-args)

Auto-wiring works only for type-hinted parameters, but if a class has other parameters you will have to configure them using the `setConstructorArgs()` method.

```
$dic = new Container();
$dic->rule("PDO")->setConsructorArgs([$dsn, $username, $password]);
```

Here new PDO instances will be configured with the proper credentials. A great benefit of this is that the container passes along the configuration only when a new object is retrieved from the container.

### Mixing Type-Hinted and Non-Type-Hinted Constructor Arguments

[](#mixing-type-hinted-and-non-type-hinted-constructor-arguments)

If a class has some type hints and some regular parameters you only specify the non-type-hinted ones with constructor args. The other ones will be auto-wired by the container.

```
class Job
{
    public function __construct(Envornment $env, $name, Logger $log)
    {
    }
}

$dic = new Container();
$dic->rule("Job")->setConstructorArgs(["job name"]);

$job = $dic->get("Job");
```

### Named Arguments

[](#named-arguments)

When passing an arguments array to any of the container's methods that expect arguments you can use the array keys to match to a specific parameter name. This is useful if you want to specify a specific argument later in the parameters list. You can also override a type-hinted parameter by specifying its name.

```
$dic->rule("Job")->setConstructorArgs([
    "name" => "job name",
    "log" => $dic->get("SysLogger"),
]);
```

### Passing Constructor Arguments During Object Creation

[](#passing-constructor-arguments-during-object-creation)

You can pass some or all constructor arguments with `getArgs()`.

```
$dic = new Container();
$pdo = $dic->getArgs("PDO", [$dsn, $username, $password]);
```

Shared Objects
--------------

[](#shared-objects)

You mark a class as shared which means that the container will return the same instance whenever the class is requested. This is a much better alternative to global variables or singletons.

```
$dic = new Container();

$dic->rule("PDO")
    ->setConsructorArgs([$dsn, $username, $password])
    ->setShared(true);

$db1 = $dic->get("PDO");
$db2 = $dic->get("PDO");
// $db1 === $db2
```

Setter Injection with Calls
---------------------------

[](#setter-injection-with-calls)

You can add method calls to a rule. Each call that is added is called in order after the object is first created. Calls work in much the same way that constructors do so they will also auto-wire if there are type-hinted parameters.

```
$dic = new Container();

$dic->rule("PDO")
    ->setConsructorArgs([$dsn, $username, $password])
    ->addCall("setAttribute", [PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION])
    ->addCall("setAttribute", [PDO::MYSQL_ATTR_INIT_COMMAND, "set names utf8"]);
```

Specifying the Class of a Rule
------------------------------

[](#specifying-the-class-of-a-rule)

You can use the `setClass()` method specify the class that is created when getting an item from the container. This is useful when you want to specify a specific subclass of an abstract base class or interface to satisfy dependencies. Rules also don't have to represent an actual class; in this case you must specify the class.

```
$dic = new Container();

$dic->rule("Psr\Log\LoggerInterface")->setClass("SysLogger");
```

Rule Inheritance
----------------

[](#rule-inheritance)

By default, all subclasses will inherit rules from their base class. In this way you can define rules for just the base class. If you don't want subclasses to inherit rules then you can override this behavior with `setInherit()`.

```
class Model {
    ...
}

class UserModel extends Model {
    ...
}

$dic->rule('Model')
    ->setShared(true);

$um1 = $dic->get('UserModel');
$um2 = $dic->get('UserModel');
// $um1 === $um2
```

### Interface Inheritance

[](#interface-inheritance)

Rules can inherit from interfaces in a limited way. If you define a rule on an interface, any classes that implement it will call its method calls in addition to their own and also use the interface rule's constructor args if it doesn't have any defined itself.

```
$dic->rule("Psr\Log\LogAwareInterface")->addCall("setLogger");
```

### The Default Rule

[](#the-default-rule)

There is a default rule that rules inherit from. You can modify this rule by selecting it with either the `defaultRule()` method or `rule('*')`.

```
$dic->defaultRule()->setShared(true);
// Now all objects are shared by default.
```

Reference Dependencies
----------------------

[](#reference-dependencies)

You can specify arguments that reference back into the container. To do this you specify arguments as `Reference` objects. You construct a reference object with an array where each item is a key into the container or a sub-container.

```
class Config
{
    public function __construct($path)
    {
        $this->data = json_decode(file_get_contents($path), true);
    }

    public function get($key)
    {
        return $this->data[$key];
    }
}

$dic = new Container();

$dic->rule(Config::class)
    ->setShared(true)
    ->setConstructorArgs(["../config.json"])

    ->rule(PDO::class)
    ->setConstructorArgs([
        new Reference([Config::class, "dsn"]),
        new Reference([Config::class, "user"]),
        new Reference([Config::class, "password"]),
    ]);

$pdo = $dic->get(PDO::class);
```

In the above example the PDO object will be constructed with information provided from the Config object in the container. Each reference specifies the `Config::class` first so the container looks for that first, then it calls `get()` with the next item in the reference's array.

### The ReferenceInterface

[](#the-referenceinterface)

The `Garden\Container` namespace defines a `ReferenceInterface` that you can implement to satisfy dependencies with custom references. There is also the `Callback` class that you can construct to satisfy a reference with a callable argument.

Setting Specific Instances in the Container
-------------------------------------------

[](#setting-specific-instances-in-the-container)

You can set a specific object instance to the container with the `setInstance()` method. When you do this the object will always be shared. One use for setInstance is to put the container into itself so that it can be a dependency. This is considered an anti-pattern by some, but can be necessary.

```
class Dispatcher
    public function __construct(Container $dic) {
        $this->dic = $dic;
    }

    public function dispatch($url) {
        $args = explode('/', $url);
        $controllerName = ucfirst(array_shift($args)).'Controller';
        $method = array_shift($args) ?: 'index';

        $controller = $this->dic->get($controllerName);

        return $this->dic->call([$controller, $method], $args)
    }
}

$dic = new Container();
$dic->setInstance(Container::class, $dic);

$dispatcher = $dic->get(Dispatcher::class);
$dispatcher->dispatch(...);
```

The `call()` method is similar to [call\_user\_func\_array](http://php.net/manual/en/function.call-user-func-array.php), but is called through the container so dependencies are auto-wired just like other methods.

Aliases
-------

[](#aliases)

You can specify a rule to be an alias of another rule. Calling get() on the alias is the same as calling get() on the rule it aliases. The following methods are used to define aliases.

- **getAliasOf(), setAliasOf()**. These methods will make the current rule alias another rule. Not that rules that are aliases will ignore other settings because they are fetched from the destination rule.
- **addAlias(), removeAlias(), getAliases()**. These methods will add an alias to the current rule. These methods are often more convenient because you usually want to configure a rule and set aliases at the same time.

### Why Use Aliases?

[](#why-use-aliases)

Aliases are useful when you have dependencies inconsistently type-hinted between base classes, classes, or interfaces and you want them all to resolve to the same shared instance.

```
class Task
{
    public function __construct(LoggerInterface $log)
    {
    }
}

class Item
{
    public function __construct(AbstractLogger $log)
    {
    }
}

$dic = new Container();

$dic->rule(LoggerInterface::class)
    ->setClass("SysLogger")
    ->setShared(true)
    ->addAlias(AbstractLogger::class);

$task = $dic->get(Task::class);
$item = $dic->get(Item::class);
// Both logs will point to the same shared instance.
```

Acknowledgements
----------------

[](#acknowledgements)

This project is heavily inspired by the excellent [DICE](https://github.com/Level-2/Dice) and to a lesser extent [Aura.Di](https://github.com/auraphp/Aura.Di) projects. Any code in the Garden Container that resembles those projects probably is from them and remains the copyright of the respective owners. The developers of those projects are much more clever than we are.

###  Health Score

49

—

FairBetter than 95% of packages

Maintenance44

Moderate activity, may be stable

Popularity36

Limited adoption so far

Community27

Small or concentrated contributor base

Maturity76

Established project with proven stability

 Bus Factor1

Top contributor holds 50.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 ~104 days

Recently: every ~210 days

Total

30

Last Release

437d ago

Major Versions

v1.5 → v2.02017-05-03

v1.5.1 → v2.0.12017-05-05

v2.0.2 → v3.0.02019-04-24

v3.0.4 → v4.0.0-beta12021-05-14

v3.1.0 → v4.0.02022-11-18

PHP version history (5 changes)v0.1.0PHP &gt;=5.4.0

v1.4PHP &gt;=5.6.0

v3.0.0PHP &gt;=7.1.0

v3.0.3PHP &gt;=7.2.0

v4.0.0PHP &gt;=7.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/da29e060f227028e8ee38bb5873ba2188fb5236b20b3dffec766c768019d8bd8?d=identicon)[tburry](/maintainers/tburry)

![](https://www.gravatar.com/avatar/ea17fedfd653c4692cf93a4faada50927cef9537dafed0dd4b1517e54fd71728?d=identicon)[charrondev](/maintainers/charrondev)

---

Top Contributors

[![tburry](https://avatars.githubusercontent.com/u/97432?v=4)](https://github.com/tburry "tburry (71 commits)")[![charrondev](https://avatars.githubusercontent.com/u/1770056?v=4)](https://github.com/charrondev "charrondev (29 commits)")[![soorajfrancis](https://avatars.githubusercontent.com/u/1746249?v=4)](https://github.com/soorajfrancis "soorajfrancis (19 commits)")[![OlivierLamyCanuel](https://avatars.githubusercontent.com/u/39598345?v=4)](https://github.com/OlivierLamyCanuel "OlivierLamyCanuel (9 commits)")[![acharron-hl](https://avatars.githubusercontent.com/u/146114816?v=4)](https://github.com/acharron-hl "acharron-hl (4 commits)")[![DaazKu](https://avatars.githubusercontent.com/u/2412909?v=4)](https://github.com/DaazKu "DaazKu (4 commits)")[![kaecyra](https://avatars.githubusercontent.com/u/248212?v=4)](https://github.com/kaecyra "kaecyra (2 commits)")[![scrutinizer-auto-fixer](https://avatars.githubusercontent.com/u/6253494?v=4)](https://github.com/scrutinizer-auto-fixer "scrutinizer-auto-fixer (1 commits)")[![linc](https://avatars.githubusercontent.com/u/117672?v=4)](https://github.com/linc "linc (1 commits)")

---

Tags

non-production

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/vanilla-garden-container/health.svg)

```
[![Health](https://phpackages.com/badges/vanilla-garden-container/health.svg)](https://phpackages.com/packages/vanilla-garden-container)
```

###  Alternatives

[symfony/dependency-injection

Allows you to standardize and centralize the way objects are constructed in your application

4.2k431.1M7.5k](/packages/symfony-dependency-injection)[illuminate/contracts

The Illuminate Contracts package.

704122.9M10.1k](/packages/illuminate-contracts)[illuminate/container

The Illuminate Container package.

31278.1M2.0k](/packages/illuminate-container)[ecotone/ecotone

Supporting you in building DDD, CQRS, Event Sourcing applications with ease.

558549.8k17](/packages/ecotone-ecotone)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

728272.9k20](/packages/civicrm-civicrm-core)[internal/dload

Downloads binaries.

98142.7k10](/packages/internal-dload)

PHPackages © 2026

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