PHPackages                             frogsystem/spawn - 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. frogsystem/spawn

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

frogsystem/spawn
================

Spawn is a simple and lightweight implementation of an IoC application container and fully compatible with container-interop.

1.0.0-rc1(10y ago)0561MITPHPPHP &gt;=5.6.0CI failing

Since Jun 14Pushed 10y ago3 watchersCompare

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

READMEChangelogDependencies (3)Versions (3)Used By (0)

Spawn
=====

[](#spawn)

[![Latest Stable Version](https://camo.githubusercontent.com/80bad9f626b2b43e4ba5f9a853bfbb2c81212346b11a0cfdd2f1941127c17464/68747470733a2f2f706f7365722e707567782e6f72672f66726f6773797374656d2f737061776e2f762f737461626c65)](https://packagist.org/packages/frogsystem/spawn)[![Total Downloads](https://camo.githubusercontent.com/68139efda4fce7ad768396723d8cdb410c9dc9c64192aa06555b79c9b0a669ba/68747470733a2f2f706f7365722e707567782e6f72672f66726f6773797374656d2f737061776e2f646f776e6c6f616473)](https://packagist.org/packages/frogsystem/spawn)[![Latest Unstable Version](https://camo.githubusercontent.com/d9ebcb42262597a3fe43eaa882c7ddbf9a2318f6fcae75136c4d1af77b0e85dd/68747470733a2f2f706f7365722e707567782e6f72672f66726f6773797374656d2f737061776e2f762f756e737461626c65)](https://packagist.org/packages/frogsystem/spawn)[![License](https://camo.githubusercontent.com/326b69fd88d25b2357a1fb3445d110760e8687468304d7b982aebb4fd75bb8a6/68747470733a2f2f706f7365722e707567782e6f72672f66726f6773797374656d2f737061776e2f6c6963656e7365)](https://packagist.org/packages/frogsystem/spawn)[![Build Status](https://camo.githubusercontent.com/8c288bedc7db4e89c8e58daab72e986234d1f00d6418352277547fc82174a5b9/68747470733a2f2f7472617669732d63692e6f72672f66726f6773797374656d2f737061776e2e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/frogsystem/spawn)[![Codacy Badge](https://camo.githubusercontent.com/3f0a28ae829cc91d86f966a5ef30e2901e052111a2f0e361bc3e12c7e826eeaf/68747470733a2f2f6170692e636f646163792e636f6d2f70726f6a6563742f62616467652f636f7665726167652f3931356234333836663930303432376538623965343238623964353736653330)](https://www.codacy.com/app/mrgrain/spawn)[![Codacy Badge](https://camo.githubusercontent.com/1229d546e42a922c55018aafe69891ed0112deb548e024b4dcd8414432982350/68747470733a2f2f6170692e636f646163792e636f6d2f70726f6a6563742f62616467652f67726164652f3931356234333836663930303432376538623965343238623964353736653330)](https://www.codacy.com/app/mrgrain/spawn)[![SensioLabsInsight](https://camo.githubusercontent.com/b2f33908ea8c2e4246e275a40bde22a51c06faf8cc2c7b78e7251debdc12a10e/68747470733a2f2f696e73696768742e73656e73696f6c6162732e636f6d2f70726f6a656374732f61363465636431322d633031642d343436662d623630652d3362346235646335356633652f6d696e692e706e67)](https://insight.sensiolabs.com/projects/a64ecd12-c01d-446f-b60e-3b4b5dc55f3e)

Spawn
-----

[](#spawn-1)

Spawn is a simple and lightweight implementation of an IoC application container and fully compatible with the [container-interop](https://github.com/container-interop/container-interop) standard.

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

[](#installation)

You can install this package through Composer:

```
composer require frogsystem/spawn

```

The packages follows the Semantic Versioning specification, and there will be full backward compatibility between minor versions.

Documentation
-------------

[](#documentation)

Boot your container by creating a new instance:

```
$app = new Container();
```

Spawn will take care of itself; you will always get the same instance as long as you use Dependency Injection and the provided factory methods.

### Get an entry

[](#get-an-entry)

Retrieve an entry from the container with the standardized `get` method; use array access for your convenience:

```
print $app->get('MyEntry'); // will print whatever value 'MyEntry' has
print $app['MyEntry']; // will do the same
```

However, if the entry is set to a callable, the callable will be invoked and its result returned instead. You will find use of this behavior to achieve different goals.

```
$app->set('MyEntry', function() {
    return 'Called!'
});
print $app->get('MyEntry'); // will print 'Called!'
```

### Set an entry

[](#set-an-entry)

To register an entry with the container, use the provided `set` method or array access:

```
$app->set('MyEntry', $value);
$app['MyEntry'] = $value;
```

#### Factory (Implementation)

[](#factory-implementation)

By design, the purpose of the container is to provide you with implementations for abstracts. To do so, you'll have to bind the abstract to a factory closure:

```
$app['ACME\MyContract'] = function() use ($app) {
    return $app->make('MyImplementation');
};
```

There is a shorthand for this and other common use cases:

```
$app['ACME\MyContract'] = $app->factory('MyImplementation'); // shorthand for the statement above (roughly)
```

#### Assignment (Instance)

[](#assignment-instance)

Binding a specific instance to an abstract can be done by normal assignment:

```
$app['ACME\MyContract'] = new MyImplementation();
```

#### Once (deferred execution)

[](#once-deferred-execution)

If you want to defer execution of the callable to the time when it is actually requested (e.g. because its expensive but not always used), use `once`:

```
$app['ACME\MyContract'] = $app->once(function() {
  return very_expensive_call(); // will be executed once when 'ACME\MyContract' is requested; returns its result afterwards
});
```

It will store the result and any further request on `ACME\MyContract` will return the stored result instead of invoking the callable.

#### One (Singleton)

[](#one-singleton)

This allows us to register implementations that behave more or less like singletons:

```
$app['ACME\MyContract'] = $app->one('ACME\MyClass'); // instantiated on first request; returns the same object every time
```

#### Protect a Callable

[](#protect-a-callable)

In case you want to store a closure or an other callable in the container, you can protect them from being invoked while retrieving:

```
$app['MyCallable'] = $app->protect(function() {
    print 'Called!';
});
$printer = $app->get('MyCallable'); // will do nothing
$printer(); // will print 'Called!'
```

#### FactoryFactory

[](#factoryfactory)

Putting all this together, you might easily create a so called `FactoryFactory` - a factory that provides you with a specific factory whenever you need one:

```
$app['UserFactory'] = $this->protect(function($username) use ($app) {
    $user = $app->one('User')->getByName($username);
    return $user;
});
$userFactory = $app->get('UserFactory');
print $userFactory('Alice')->getName(); // will print 'Alice'
print $userFactory('Bob')->getName(); // will print 'Bob'
```

### Check for an entry

[](#check-for-an-entry)

Use the `has` method to check whether an entry exists or not:

```
$app->has('MyEntry'); // true or false
```

### Internals

[](#internals)

You must only use the container to define your abstracts. They are meant to be shared with other containers and an implementation may be replaced by a different one during runtime. However, you will have cases where your code depends on a specific instance. Those internals are hold separately from the rest of the container and therefore have to be set as properties:

```
$app->config = $app->make('MyConfig');
```

Using the magic setter will provide you with the same API as set out above. You may also define an internal explicit as class property, but a callable **will not** be invoked on retrieval if set this way.

Get your internals through properties as well:

```
print $app->version;
```

To set a value for both, an internal and a normal container entry, simply chain the assignments:

```
$app->config = $app['ConfigContract'] = $this->factory('MyConfig');
```

### Dependency Injection

[](#dependency-injection)

Spawn provides you with two methods for using Dependency Injection and the Inversion of Control pattern. Use `make` to create new instances of abstracts; and use `invoke` to execute callables with filled-in dependencies. Both methods will using Dependency Injection to resolve their arguments. This means, if the invoked callable or class constructor has **any** parameters, those methods will use the container to find a suitable implementation and inject it in the argument list.

Additional any value retrieved from the container via `get` or `ArrayAccess` which is a callable, will be invoked using the very same `invoke` method. Thus they will also have their dependencies injected.

Use `make` to create an object from a concrete class:

```
class MyClass {
    __construct(OtherClass $other);
}
$app->make('MyClass');
```

When calling `invoke` with a callable as argument, Spawn will try resolve any arguments:

```
class MyObject {
    function print() {
        print 'Found!!'
    }
}
$callable = function(MyObject $object) {
    $object->print();
}
$app->invoke($callable); // will print 'Found!'
```

#### Additional arguments

[](#additional-arguments)

You may also pass additional arguments in an array to these methods. It allows you to override dependency lookup on a per case basis. During the argument selection, entries will first be looked up in the array, matching the parameters class and name against array keys.

```
class MyClass {
    __construct(OtherClass $other, $id);
    function do($name) {
        print $name;
    }
}
$object = $app->make('MyClass', ['id' => 42]); // $id will be 42, $other will be resolved through the container
$app->invoke([$object, 'do'], ['name' => 'Spawn']); // will print 'Spawn'
```

As mentioned above, `get` will also invoke a callable before returning it. Thus you may pass additional arguments to this method, as well.

### Delegate lookup

[](#delegate-lookup)

Delegate lookup is a featured introduced by the Container Interoperability standard. A request to the container is performed within the container. But **if the fetched entry has dependencies, instead of performing the dependency lookup in the container, the lookup is performed on the delegate container**. In other words: Whenever dependency injection happens, dependencies will be resolved through the delegate container.

Dependency lookup in Spawn is always delegated. By default the container delegates the lookup to itself. Set a different delegate container via constructor argument or use the use the `delegate` method:

```
$app = new Container($delegateContainer);
$app->delegate($delegateContainer);
```

Delegate lookup enables sharing of entries across containers and allows to build up a **delegation queue**. See **Design principles** to learn how to utilize this feature properly.

Design principles
-----------------

[](#design-principles)

- Implements container-interop
- Implements delegate lookup
- Separates storage of 'public' abstracts and internals
- Adding entries always via the same single method; all other features are implemented using closures
- Enforce users to use the delegate lookup feature and the delegation queue

###  Health Score

23

—

LowBetter than 27% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity9

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 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 ~307 days

Total

2

Last Release

3684d ago

PHP version history (2 changes)1.0.0-beta1PHP &gt;=5.4.0

1.0.0-rc1PHP &gt;=5.6.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/853d3ba7366c4236ac911df132e6830b872fa88d43c0e6fcff123d78066faa45?d=identicon)[mrgrain](/maintainers/mrgrain)

---

Top Contributors

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

---

Tags

containercontainer-interopiocdic

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/frogsystem-spawn/health.svg)

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

###  Alternatives

[psr/container

Common Container Interface (PHP FIG PSR-11)

10.0k1.0B3.7k](/packages/psr-container)[php-di/php-di

The dependency injection container for humans

2.8k48.9M994](/packages/php-di-php-di)[league/tactician-container

Tactician integration for any container implementing PSR-11

7710.1M23](/packages/league-tactician-container)[miladrahimi/phpcontainer

Dependency injection (IoC) container for PHP projects

1322.7k2](/packages/miladrahimi-phpcontainer)[slince/di

A flexible dependency injection container

20260.4k6](/packages/slince-di)[capsule/di

A PSR-11 compliant autowiring dependency injection container.

2857.5k2](/packages/capsule-di)

PHPackages © 2026

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