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

ActiveLibrary[Framework](/categories/framework)

mb4it/container
===============

PSR-11 DI container with contextual bindings, tags, and attributes

07PHP

Since Feb 15Pushed 3mo agoCompare

[ Source](https://github.com/Dictator90/mb-container)[ Packagist](https://packagist.org/packages/mb4it/container)[ RSS](/packages/mb4it-container/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependenciesVersions (1)Used By (0)

mb/container
============

[](#mbcontainer)

PSR-11 DI container with contextual bindings, tags, and attributes.

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

[](#requirements)

- PHP 8.2+
- `psr/container` ^2.0

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

[](#installation)

```
composer require mb/container
```

Basic usage
-----------

[](#basic-usage)

```
use MB\Container\Container;

$container = new Container();

// Bind interface to implementation
$container->bind(LoggerInterface::class, FileLogger::class);

// Resolve
$logger = $container->get(LoggerInterface::class);

// Singleton
$container->singleton(Cache::class, RedisCache::class);
$cache = $container->make(Cache::class);
```

Contextual bindings
-------------------

[](#contextual-bindings)

Inject different implementations depending on the class that is being built:

```
$container->bind(LoggerInterface::class, NullLogger::class);

$container->when(ServiceA::class)
    ->needs(LoggerInterface::class)
    ->give(FileLogger::class);

// ServiceA receives FileLogger; other classes receive NullLogger
$service = $container->make(ServiceA::class);
```

You can also use a callable:

```
$container->when(ServiceA::class)
    ->needs(LoggerInterface::class)
    ->give(fn (Container $c) => $c->make(FileLogger::class));
```

Attribute injection
-------------------

[](#attribute-injection)

Override the type-hinted dependency with `#[Inject]`:

```
use MB\Container\Attributes\Inject;

class MyService
{
    public function __construct(
        #[Inject(FileLogger::class)]
        LoggerInterface $logger
    ) {}
}
```

Class attributes
----------------

[](#class-attributes)

You can declare alias, tag, and singleton on a class and register it in one call with `registerClass()`:

- **`#[Alias(string $alias)]`** — register the class under an additional name (e.g. `$container->make('logger')`).
- **`#[Tag(string $tag)]`** — add the class to a tag (multiple `#[Tag(...)]` allowed).
- **`#[Singleton]`** — register as shared (one instance per container).

```
use MB\Container\Container;
use MB\Container\Attributes\Alias;
use MB\Container\Attributes\Tag;
use MB\Container\Attributes\Singleton;

#[Singleton]
#[Alias('logger')]
#[Tag('handlers')]
class FileLogger implements LoggerInterface {}

$container = new Container();
$container->registerClass(FileLogger::class);
// Same as: $container->singleton(FileLogger::class, FileLogger::class);
//           $container->alias(FileLogger::class, 'logger');
//           $container->tag([FileLogger::class], 'handlers');

$container->make('logger');       // FileLogger instance
$container->tagged('handlers');  // [FileLogger instance]
```

Use `registerClass()` when you prefer to keep registration metadata on the class instead of repeating `bind` / `alias` / `tag` calls.

Tags and tagged resolution
--------------------------

[](#tags-and-tagged-resolution)

Tag multiple bindings and resolve them as a list:

```
$container->bind(FileLogger::class, FileLogger::class);
$container->bind(NullLogger::class, NullLogger::class);
$container->tag([FileLogger::class, NullLogger::class], 'loggers');

$loggers = $container->tagged('loggers'); // [FileLogger instance, NullLogger instance]
```

Extending and events
--------------------

[](#extending-and-events)

Decorate or observe resolutions:

```
$container->extend(LoggerInterface::class, function (object $instance, Container $c) {
    return new DecoratingLogger($instance);
});

$container->resolving(LoggerInterface::class, function (object $instance) {
    // called when resolving
});

$container->afterResolving(LoggerInterface::class, function (object $instance) {
    // called after resolution
});
```

Aliases
-------

[](#aliases)

```
$container->bind(FileLogger::class, FileLogger::class);
$container->alias(FileLogger::class, 'logger');

$logger = $container->make('logger');
$container->has('logger'); // true
```

Rebinding
---------

[](#rebinding)

Run a callback when a binding is replaced (e.g. by `bind()` or `instance()`):

```
$container->rebinding(LoggerInterface::class, function (Container $c, object $instance) {
    // previous instance when binding changed
});
```

Compilation
-----------

[](#compilation)

Compile bindings into factories for faster resolution (e.g. in production):

```
$container->bind(LoggerInterface::class, FileLogger::class);
$container->bind(ServiceA::class, ServiceA::class);

$container->compile();

$service = $container->make(ServiceA::class); // uses compiled factory
```

You can keep calling `bind()`, `instance()`, or `when()->give()` after `compile()`. The compiled factory for the affected abstract (or concrete, for contextual rules) is then invalidated, so the next `make()` uses the current bindings. To re-optimize everything after configuration changes, call `compile()` again.

For maximum resolution speed (Symfony-like), use **`compileToFile(string $path)`**: the container generates a PHP class file and uses it for resolution. Bindings changed after `compileToFile()` are invalidated for that abstract; the next `make()` uses the normal path for them. Call `compileToFile($path)` again to regenerate after configuration changes.

You can also inject a pre-filled `CompiledRepository` via the constructor or `setCompiledRepository()`.

PSR-11
------

[](#psr-11)

- `get(string $id): mixed` — resolves the entry; throws `NotFoundExceptionInterface` if not found.
- `has(string $id): bool` — returns whether the container can resolve the id (aliases are resolved).

Benchmark
---------

[](#benchmark)

A small script measures resolve time for a dependency graph (interfaces and services) with and without compilation:

```
php benchmarks/container_benchmark.php
```

It reports time in ms and resolves per second for MB container (with/without compile) and, when installed, for Laravel and Symfony:

```
composer require --dev illuminate/container   # optional: Laravel
composer require --dev symfony/dependency-injection   # optional: Symfony
php benchmarks/container_benchmark.php
```

License
-------

[](#license)

MIT.

###  Health Score

20

—

LowBetter than 14% of packages

Maintenance55

Moderate activity, may be stable

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity12

Early-stage or recently created project

 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.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/75324054?v=4)[Maxim Bezvodinskikh](/maintainers/Dictator90)[@Dictator90](https://github.com/Dictator90)

---

Top Contributors

[![Dictator90](https://avatars.githubusercontent.com/u/75324054?v=4)](https://github.com/Dictator90 "Dictator90 (5 commits)")

### Embed Badge

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

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

###  Alternatives

[laravel/passport

Laravel Passport provides OAuth2 server support to Laravel.

3.4k85.0M532](/packages/laravel-passport)[nolimits4web/swiper

Most modern mobile touch slider and framework with hardware accelerated transitions

41.8k177.2k1](/packages/nolimits4web-swiper)[laravel/dusk

Laravel Dusk provides simple end-to-end testing and browser automation.

1.9k36.7M259](/packages/laravel-dusk)[laravel/prompts

Add beautiful and user-friendly forms to your command-line applications.

712181.8M596](/packages/laravel-prompts)[cakephp/chronos

A simple API extension for DateTime.

1.4k47.7M121](/packages/cakephp-chronos)[laravel/pail

Easily delve into your Laravel application's log files directly from the command line.

91545.3M590](/packages/laravel-pail)

PHPackages © 2026

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