PHPackages                             david2m/syringe - 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. [Framework](/categories/framework)
4. /
5. david2m/syringe

ActiveLibrary[Framework](/categories/framework)

david2m/syringe
===============

A feature-rich PHP dependency injector that just makes sense.

v1.0.0(9y ago)019MITPHPPHP &gt;=5.4.0

Since Aug 11Pushed 9y ago1 watchersCompare

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

READMEChangelogDependencies (1)Versions (2)Used By (0)

PHP Dependency Injector
=======================

[](#php-dependency-injector)

A dependency injection container capable of:

1. Auto-wiring.
2. Delegating object creation to factories.
3. Dealing with multiple instances of the same class.
4. Calling methods after instantiation.
5. Mapping interfaces and abstract classes to concrete implementations.
6. Circular dependency detection.
7. And more.

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

[](#table-of-contents)

##### [- Requirements](#requirements)

[](#--requirements)

##### [- Installation](#installation)

[](#--installation)

##### [- Instantiating an Object](#instantiating-an-object)

[](#--instantiating-an-object)

##### [- Unresolvable Arguments](#unresolvable-arguments)

[](#--unresolvable-arguments)

##### [- Setting Arguments](#setting-arguments)

[](#--setting-arguments)

##### [- Mapping to Concrete Implementations](#mapping-to-concrete-implementations)

[](#--mapping-to-concrete-implementations)

##### [- Calling a Method After Instantiation](#calling-a-method-after-instantiation)

[](#--calling-a-method-after-instantiation)

##### [- Using Factories (Delegating Instantiation)](#using-factories-delegating-instantiation)

[](#--using-factories-delegating-instantiation)

##### [- Multiple Instances of the Same Class](#multiple-instances-of-the-same-class)

[](#--multiple-instances-of-the-same-class)

##### [- Sharing Instances](#sharing-instances)

[](#--sharing-instances)

##### [- Invoking a Method or Function](#invoking-a-method-or-function)

[](#--invoking-a-method-or-function)

Requirements
------------

[](#requirements)

Syringe requires PHP 5.4 or higher.

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

[](#installation)

#### Composer

[](#composer)

```
composer require david2m/syringe

```

Instantiating an Object
-----------------------

[](#instantiating-an-object)

For the sake of simplicity (this being the first example and all), say we want to instantiate an object which has no dependencies:

```
class UserMapper
{
}
```

```
$mapper = $injector->make('UserMapper');
```

### Recursively Resolving Parameters

[](#recursively-resolving-parameters)

```
class PdoAdapter
{
}
```

The `UserMapper` now depends on a `PdoAdapter`

```
// UserMapper.php
public function __construct(PdoAdapter $pdoAdapter)
{
}
```

```
$mapper = $injector->make('UserMapper');
```

When making a `UserMapper` the injector discovers that it depends on a `PdoAdapter` so it creates a `PdoAdapter` object first and injects it into the `UserMapper`.

Unresolvable Arguments
----------------------

[](#unresolvable-arguments)

Two scenarios exist where it is impossible to automatically resolve an argument:

1. No type-hint exists - In this situation you must explicitly tell the injector what the argument is. See [setting arguments](#setting-arguments).
2. The type-hint is an interface or abstract class - See [mapping to concrete implementations](#mapping-to-concrete-implementations).

Setting Arguments
-----------------

[](#setting-arguments)

```
class PdoAdapter
{
  public function __construct($host, $user, $password, $schema)
  {
  }
}
```

```
$constructor = $injector->getConstructor('PdoAdapter');

// Setting one argument
$constructor->setArgument('host', 'localhost');

// Setting multiple arguments
$constructor->addArguments([
  'host' => 'localhost',
  'user' => 'david'
]);
```

You can set the arguments of any method, not just the constructor.

```
$injector
  ->getMethod('PdoAdapter', 'someMethod')
  ->setArgument('name', 'value');
```

You can also set arguments on the fly:

```
$injector->make('PdoAdapter', [
  'host' => 'localhost',
  'user' => 'david'
]);
```

Arguments set on the fly always take precedence over arguments set prior to calling `make()`.

This is useful when [adding calls](#calling-a-method-after-instantiation) to a method or using the [invoke()](#invoking-a-method-or-function) method.

### Callable Arguments

[](#callable-arguments)

Callable arguments get invoked and their return value gets passed into the method.

```
$injector
  ->getConstructor('PdoAdapter')
  ->setArgument('user', function()
  {
    return 'bob';
  });
```

**If the type-hint of the parameter is callable and the set argument is callable then the argument will NOT be invoked before passing it into the method.**

### String Argument Resolved to an Object

[](#string-argument-resolved-to-an-object)

You can set a class name argument for a parameter which has a class or interface type-hint.

```
class UserMapper
{
  public function __construct(PdoAdapter $pdoAdapter)
  {
  }
}
```

```
$injector
  ->getConstructor('UserMapper')
  ->setArgument('pdoAdapter', 'PdoAdapter');
```

When the injector is resolving the argument it will notice it is a string but the type-hint is a class. It will then resolve the string argument (class name) into an object.

This technique is especially powerful when you need to use [multiple instances of the same class](#multiple-instances-of-the-same-class). Say you have two databases, a local and a remote one and both obviously have different connection details. The `UserMapper` connects to the local database and the `Logger` connects to a remote database.

```
class UserMapper
{
  public function __construct(PdoAdapter $pdoAdapter)
  {
  }
}
```

```
class Logger
{
  public function __construct(PdoAdapter $pdoAdapter)
  {
  }
}
```

Both objects need a different instance of a `PdoAdapter`, one which can connect to the local database and another which can connect to the remote database.

```
$injector
  ->getConstructor('PdoAdapter')
  ->addArguments([
      'host' => 'localhost',
      'user' => 'local_user',
      'password' => 'local_password',
      'schema' => 'local_database_name'
    ]);

$injector
  ->getConstructor('PdoAdapter#remote')
  ->addArguments([
      'host' => '103.243.0.78',
      'user' => 'remote_user',
      'password' => 'remote_password',
      'schema' => 'remote_database_name'
    ]);

$injector
  ->getConstructor('Logger')
  ->setArgument('pdoAdapter', 'PdoAdapter#remote');

$mapper = $injector->make('UserMapper');
$logger = $injector->make('Logger');
```

The `UserMapper` will get the `#default` instance of the `PdoAdapter` and the `Logger` will get the `#remote` instance of the `PdoAdapter`. For more information about dealing with multiple instances click [here](#multiple-instances-of-the-same-class).

Mapping to Concrete Implementations
-----------------------------------

[](#mapping-to-concrete-implementations)

```
interface DatabaseAdapterInterface
{
}
```

```
class PdoAdapter implements DatabaseAdapterInterface
{
}
```

```
// UserMapper.php
public function __construct(DatabaseAdapterInterface $dbAdapter)
{
}
```

When trying to make a `UserMapper` the injector will throw an `InjectorException` because it cannot resolve `DatabaseAdapterInterface` to a concrete implementation. To prevent this you simply map the interface to a concrete implementation i.e. a class which implements the interface.

**You can also map abstract classes to concrete implementations.**

```
$injector->setMapping('DatabaseAdapterInterface', 'PdoAdapter');

// You can also add multiple mappings at once
$injector->addMappings([
  'DatabaseAdapterInterface' => 'PdoAdapter',
  'AbstractClassName' => 'AnotherConcreteImplementation'
]);
```

Calling a Method After Instantiation
------------------------------------

[](#calling-a-method-after-instantiation)

```
// PdoAdapter.php
public function connect()
{
}
```

```
$injector
  ->getMethod('PdoAdapter', 'connect')
  ->addCall();

$pdoAdapter = $injector->make('PdoAdapter');
```

Once the `PdoAdapter` has been instantiated the `connect()` method will be called before the object is returned. If the method being called has any parameters they will be resolved and passed into the method. If the method has any [unresolvable arguments](#unresolvable-arguments) you must [set them](#setting-arguments) before you make the object or else pass them to the `addCall()` method.

Using Factories (Delegating Instantiation)
------------------------------------------

[](#using-factories-delegating-instantiation)

A factory consists of a regular expression and a callable. The regular expression is matched against the name of the class being made, if there is a match then the instantiation of the object is delegated to the factory.

**If the class name you're trying to match contains backslashes you do not need to escape them, this is done automatically by the injector.**

```
// The regular expression ^PdoAdapter$ will match the classname PdoAdapter
$injector->setFactory('^PdoAdapter$', function()
{
  return new PdoAdapter('localhost', 'david', 'mypassword', 'my_database_name');
});

$pdoAdapter = $injector->make('PdoAdapter'); // Factory instantiates the object.
```

### Advanced Factory Usage

[](#advanced-factory-usage)

Let's say you have some services in your application which reside in the `Service` namespace. For some reason you don't want the injector to instantiate any of the services and want to delegate that job to your own `ServiceFactory`.

```
namespace Service;

class Recognition
{
}

class Shopping
{
}
```

```
class ServiceFactory
{
  public function create($className)
  {
    // Instantiate and return the object.
  }
}
```

```
$injector->setFactory('^Service\\', function($className, ServiceFactory $serviceFactory)
{
  return $serviceFactory->create($className);
});

$recognition = $injector->make('Service\Recognition');
$shopping = $injector->make('Service\Shopping');
```

The instantiation of any class name that begins with `Service\` is delegated to the callable factory. If the callable factory has a parameter named `$className` then the injector will pass the full name of the class which matched the regular expression of the factory.

Multiple Instances of the Same Class
------------------------------------

[](#multiple-instances-of-the-same-class)

So far we have only dealt with a single instance of the same class. Sometimes you may want multiple instances of the same class. Such a use case would be dealing with multiple databases. Your application may need to connect to a local database and a remote database.

When making an object, setting its parameters or adding calls to its methods you can specify which instance of the object you are referring to by putting a `#instance-name` after the class name. If you do not supply an instance name then you are dealing with the `#default` instance of the class.

```
$injector->make('PdoAdapter');

// Is the same as
$injector->make('PdoAdapter#default');
```

Two different instances of the same class:

```
$injector
  ->getConstructor('PdoAdapter')
  ->addArguments([
      'host' => 'localhost',
      'user' => 'local_user',
      'password' => 'local_password',
      'schema' => 'local_database_name'
    ]);

$injector
  ->getConstructor('PdoAdapter#remote')
  ->addArguments([
      'host' => '103.243.0.78',
      'user' => 'remote_user',
      'password' => 'remote_password',
      'schema' => 'remote_database_name'
    ]);

$localPdoAdapter = $injector->make('PdoAdapter');
$remotePdoAdapter = $injector->make('PdoAdapter#remote');

var_dump($localPdoAdapter === $remotePdoAdapter); // bool(false)
```

Sharing Instances
-----------------

[](#sharing-instances)

By default, if an object is created by the injector it is stored and used every time an instance of that object is needed.

```
$userOne = $injector->make('Entity\User');
$userTwo = $injector->make('Entity\User');

var_dump($userOne === $userTwo); // bool(true)
```

You can tell the injector to always create a new instance of an object:

```
$injector->singleton('Entity\User', false);

$userOne = $injector->make('Entity\User');
$userTwo = $injector->make('Entity\User');

var_dump($userOne === $userTwo); // bool(false)
```

Sharing an object:

```
$injector->share([$pdoAdapter]);
```

Sharing an object and specifying the instance name:

```
$injector->share(['remote' => $remotePdoAdapter]);

// To retrieve the $remotePdoAdapter
$remotePdoAdapter = $injector->make('PdoAdapter#remote');
```

Invoking a Method or Function
-----------------------------

[](#invoking-a-method-or-function)

The `invoke()` method accepts any valid PHP [callable](https://secure.php.net/manual/en/language.types.callable.php) and an optional second parameter which contains arguments you want to pass into the method/function when it is invoked.

###  Health Score

25

—

LowBetter than 37% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity6

Limited adoption so far

Community4

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

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

Unknown

Total

1

Last Release

3563d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/4de49ec7158e719200c067d48461cac630c833fbb9f2885902fa92482b6ec8a5?d=identicon)[stackoh](/maintainers/stackoh)

---

Tags

dependency-injectioniocdicinjector

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/david2m-syringe/health.svg)

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

###  Alternatives

[rdlowrey/auryn

Auryn is a dependency injector for bootstrapping object-oriented PHP applications.

7262.2M76](/packages/rdlowrey-auryn)[nette/di

💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP features.

92140.6M1.4k](/packages/nette-di)[yiisoft/injector

PSR-11 compatible injector. Executes a callable and makes an instances by injecting dependencies from a given DI container.

942.8M38](/packages/yiisoft-injector)[mouf/mouf

The Mouf PHP framework: an open-source PHP framework providing an easy way to download, install, use and reuse components, with a graphical user interface.

55146.0k17](/packages/mouf-mouf)[joomla/di

Joomla DI Package

15391.2k11](/packages/joomla-di)

PHPackages © 2026

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