PHPackages                             mindplay/boxy - 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. mindplay/boxy

Abandoned → [mindplay/unbox](/?search=mindplay%2Funbox)ArchivedLibrary[Utility &amp; Helpers](/categories/utility)

mindplay/boxy
=============

Open, simple, type-hinted service container

2.0.0(11y ago)922[1 issues](https://github.com/mindplay-dk/boxy/issues)LGPL-3.0+PHP

Since May 14Pushed 10y ago2 watchersCompare

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

READMEChangelog (2)Dependencies (2)Versions (3)Used By (0)

Boxy
====

[](#boxy)

Open, simple, type-hinted (and type-checked) dependency injection container for PHP 5.5 and up.

⚠️ **WARNING**: this project is unmaintained and was superseded by [Unbox](https://github.com/mindplay-dk/unbox).

Definitely inspired by [Pimple](http://pimple.sensiolabs.org/) but optimized for full IDE support, e.g. design-time and run-time type-checking, both on the provider and consumer side, in modern IDEs such as [Php Storm](https://www.jetbrains.com/phpstorm/) ✌️

[![Build Status](https://camo.githubusercontent.com/1c796fb7be2f52ec5cdeac9ecca7f7678bbe73a35822451986dde22b5985fcf9/68747470733a2f2f7472617669732d63692e6f72672f6d696e64706c61792d646b2f626f78792e706e67)](https://travis-ci.org/mindplay-dk/boxy)

[![Code Coverage](https://camo.githubusercontent.com/41c329b13058adeaa3e283eaa06c136d9ba70e209e5ea5c4976960f3d9d07c39/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6d696e64706c61792d646b2f626f78792f6261646765732f636f7665726167652e706e67)](https://scrutinizer-ci.com/g/mindplay-dk/boxy/)

[![Scrutinizer Code Quality](https://camo.githubusercontent.com/68de78bd70c00be9a827f2269f57498d532e7519b2c706694f47ef14b1bcb036/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6d696e64706c61792d646b2f626f78792f6261646765732f7175616c6974792d73636f72652e706e67)](https://scrutinizer-ci.com/g/mindplay-dk/boxy/)

### Basic Usage

[](#basic-usage)

Create an instance of the Container:

```
use mindplay\boxy\Container;

$container = new Container();
```

Service objects can be inserted directly (eaglerly) into the container:

```
$container->insertService(new Database());
```

Or you can register factory functions to create services as late as possible:

```
$container->registerService(
    Mapper::class,
    function (Database $db) {
        // type-hinted argument gets resolved and Database instance gets provided

        return new Mapper($db); // return type will be checked
    }
);
```

Consumers can then ask for services by providing a function to be invoked:

```
$container->invoke(function (Database $db, Mapper $mapper) {
    // type-hinted arguments are resolved - the Mapper and Database instance
    // are constructed as needed and provided for the consumer function.
});
```

You can also define optional dependencies, by using optional arguments:

```
$container->invoke(function (Optional $stuff = null) {
    if ($stuff) {
        // ...
    }
});
```

In this example, if class `Optional` has not been registered in the container, the function will still be invoked, but will be passed a `null` argument - be sure to check for presence of optional arguments.

May be obvious, but note that, even if all the arguments are optional, and all the services/components are unavailable, the function will still be invoked.

### Component Factory Usage

[](#component-factory-usage)

You can register factory functions to create components on demand:

```
$container->registerComponent(
    ArticleFinder::class,
    function (Database $db) {
        return new ArticleFinder($db);
    }
);
```

Consumers can then ask for a new component instance the same way they ask for services:

```
$container->invoke(function (ArticleFinder $finder) {
    // a new ArticleFinder component is created every time you call invoke
});
```

In other words, the syntax is the same; whoever populates the container decides whether a given type should be registered as a service (same every time) or as a component (new instance every time.)

### Named Services and Components

[](#named-services-and-components)

You can optionally name your service/component definitions - this is useful in cases where you have two distinct instances of the same class, or wish to provide two distinct implementations of an abstract class or interface. Every public API method has a named counterpart - for example, here we register two different cache components, both to a common interface:

```
$container->registerNamed('file_cache', CacheInterface::class, function () {
    return new FileCache(...);
});

$container->registerNamed('memory_cache', CacheInterface::class, function () {
    return new MemoryCache(...);
});
```

Consumers then ask for these services by using argument names matching the names they were registered for - in this case:

```
$container->invoke(function (CacheInterface $file_cache) {
    echo get_class($file_cache); // => FileCache
});

$container->invoke(function (CacheInterface $disk_cache) {
    echo get_class($disk_cache); // => DiskCache
});
```

The `invoke()` method always tries to provide services/components with a matching name first, but will fall back to a service/component definition matching only the type - so, in a unit-testing scenario (where you don't have the calls to `registerNamed` above) you could mock both of the dependencies in the example above, by registering a single mock cache:

```
$container->registerService(CacheInterface::class, function () {
    return new MockCache();
});
```

The `invoke()` method will now provide `MockCache` instances for any `CacheInterface`argument, regardless of whether the name matches.

The `registerComponent()` method also has a `registerNamedComponent()` counterpart, and so on.

### Configuring Services and Components

[](#configuring-services-and-components)

You can register additional configuration functions for a service or component:

```
$container->configure(function (Database $db) {
    $db->exec("set names utf8");
});
```

Configuration functions will be executed as late as possible, e.g. the first time you call `invoke()` and ask for the service or component. (If a service has already been initialized, the configuration function will execute immediately.)

### Overriding Services

[](#overriding-services)

You can override a previously registered service creation function:

```
$container->overrideService(
    Database::class,
    function () {
        return new Database();
    }
);
```

You can override component factory functions as well, at any time; note that overriding a service creation function is only possible until the service is initialized - an attempted override after initialization will cause an exception.

### Packaged Service Providers

[](#packaged-service-providers)

You can package service/component definitions for easy reuse by implementing the `Provider` interface:

```
use mindplay\boxy\Provider;

class ServiceProvider implements Provider
{
    public function register(Container $container)
    {
        $container->registerService(
            Database::class,
            function () {
                return new Database();
            }
        );
    }
}
```

Then register your custom provider with your container instance:

```
$container->register(new ServiceProvider);
```

Note that providers get registered immediately - which means you should still use `registerService()` rather than `insertService()` if you want lazy initialization.

### Consumer Interface

[](#consumer-interface)

You can make components explicitly interoperable with the service container by implementing the `Consumer` interface, which is simply a method that returns a function to `invoke()` - this provides a means of opening a class to dependency injection (also during tests, independently of a `Container` instance) without adding setters or making things public.

For example:

```
class PetStore implements Consumer
{
    protected $cat;
    protected $dog;

    public function getInjector()
    {
        return function (Cat $cat, Dog $dog) {
            $this->cat = $cat;
            $this->dog = $dog;
        };
    }
}
```

Now, assuming you have a `Container` already configured to provide instances of `Cat` and `Dog`, you can provide those dependencies by passing a `PetStore` to the `provide()` method:

```
$container->provide($store = new PetStore);
```

After this call, the function returned by the `getInjector()` method has been called, and the `Cat` and `Dog` dependencies have been provided.

###  Health Score

29

—

LowBetter than 59% of packages

Maintenance18

Infrequent updates — may be unmaintained

Popularity12

Limited adoption so far

Community8

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

Total

2

Last Release

4021d ago

Major Versions

1.0.0 → 2.0.02015-05-15

### Community

Maintainers

![](https://www.gravatar.com/avatar/9445f567f43ee7a963270651e40e533634586f959e4df3d5398d001b1cb49be8?d=identicon)[mindplay.dk](/maintainers/mindplay.dk)

---

Top Contributors

[![mindplay-dk](https://avatars.githubusercontent.com/u/103348?v=4)](https://github.com/mindplay-dk "mindplay-dk (16 commits)")

### Embed Badge

![Health badge](/badges/mindplay-boxy/health.svg)

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

###  Alternatives

[pmaslak/php-obfuscator

PHP obfuscator

222.6k](/packages/pmaslak-php-obfuscator)

PHPackages © 2026

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