PHPackages                             paket/bero - 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. paket/bero

ActiveLibrary

paket/bero
==========

Dependency injection container

0.4(4y ago)2959↓100%1MITPHPPHP &gt;=7.2

Since Jan 23Pushed 4y ago3 watchersCompare

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

READMEChangelogDependencies (1)Versions (5)Used By (1)

Bero
====

[](#bero)

Bero (*Swedish* depend) is a dependency injection container for PHP. By inspecting class constructors Bero can instantiate classes and all their class dependencies with any depth. It could be described as a on-the-fly factory creator.

[![](https://github.com/paketphp/bero/workflows/tests/badge.svg)](https://github.com/paketphp/bero/workflows/tests/badge.svg)

Usage
-----

[](#usage)

```
$bero = new StrictBero();
$bero->callCallable(function (ArticleRepository $articleRepository, Json $json) {
   $article = $articleRepository->getArticleById(17);
   echo $json->encode($article);
});

```

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

[](#installation)

`composer require paket/bero`

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

[](#requirements)

Requires PHP 7.2 or higher.

General
-------

[](#general)

Bero inspect method or function parameters for callables or class constructors to be able to instantiate those parameters. To be able to instantiate a parameter it has to have class type, if a type is an interface Bero has to be configured beforehand for what implementation to pick. Every class must either already be loaded or be able to be loaded by autoloader.

This means that if a class with constructor parameter that is either missing or of scalar type, Bero can't instantiate it. Bero has a configuration API for those use cases.

When the same class is used multiple times through the dependency chain Bero reuses the same object instance for that class for the entire lifetime of Bero (ideally the length of a request). This is what you probably want in the vast majority of cases, e.g. only one class instance per request for a database repository.

This also means that any state stored within an instance will be shared with all usages of that class during the lifetime of Bero, for PHP that works pretty well because of PHP's share nothing between request, i.e. shared state will only be for that request, meaning you can use Bero for a singleton pattern per request basis, e.g. keeping track of the current logged in user for this request.

If it is needed to create a new instance for each usage it is recommended to create a factory class instead, depend on the factory class and then ask the factory class for each usage.

### Implementations

[](#implementations)

Bero has multiple implementations for usage in different scenarios

- MinimalBero
    - as small as Bero can be for better performance
    - ideal use for production
- StrictBero
    - better error reporting
    - ideal use for development &amp; testing
- BeroContainer
    - [PSR-11](https://www.php-fig.org/psr/psr-11/) complaint container
    - Wrapper around Bero

### Instantiation

[](#instantiation)

#### MinimalBero

[](#minimalbero)

```
$bero = new \Paket\Bero\MinimalBero();
```

#### StrictBero

[](#strictbero)

```
$bero = new \Paket\Bero\StrictBero();
```

### Dependency injection

[](#dependency-injection)

Assume these classes

```
class A
{
}

class B
{
    public $a;

    public function __construct(A $a)
    {
        $this->a = $a;
    }

    public function doStuff(): int
    {
        return 17;
    }
}
```

#### Construct class instances &amp; retrieve them

[](#construct-class-instances--retrieve-them)

Instantiate class `B` that has `A` as a dependency

```
$b = $bero->getObject(B::class);
assert(is_object($b->a));
$b->doStuff();
```

Or a `callable` can be used to retrieve multiple class instances and optionally return a result.

```
$int = $bero->callCallable(function (A $a, B $b) {
    assert($a === $b->a);
    return $b->doStuff();
});
assert($int === 17);
```

#### Use existing class instance together with Bero

[](#use-existing-class-instance-together-with-bero)

Assume our application already has a class instance of `A` that we want to use together with Bero.

```
$bero->addObject(A::class, $a);
$b = $bero->getObject(B::class);
assert($a === $b->$a);
```

#### Custom factory for creating class instance

[](#custom-factory-for-creating-class-instance)

You can also provide your own `callable` to be called when Bero needs to instantiate a class.

```
$bero->addCallable(B::class, function (A $a) {
    return new B($a);
});
$b = $bero->getObject(B::class);
```

Note that the supplied callable can also depend on class dependencies to be used to instantiate your class.

Callable will only be called when needed &amp; only once &amp; then Bero will cache the result.

`addCallable()` is good way to handle non-instantiable classes.

```
class C
{
    public function __construct(int $i)
    {
    }
}

$bero->addCallable(C::class, function () {
    return new C(17);
});
```

#### Map interface to implementation

[](#map-interface-to-implementation)

If your class depends on an interface you need to tell Bero which implementation to be used.

```
interface I
{
}

class D implements I
{
}

$bero->addInterface(I::class, D::class);
$i = $bero->getObject(I::class);
assert($i instanceof D);
```

#### Make Bero self aware

[](#make-bero-self-aware)

Normally you would only call Bero once when bootstrapping the application, e.g. instantiate the controller &amp; all it's dependencies &amp; then execute it.

However sometimes your application makes a fork in it's execution path that is dependent on some calculated value that is unknown at bootstrap &amp; because you only want to instantiate the execution path that is needed &amp; not all of them you can depend on Bero further down in your application.

Assume following

```
interface Service
{
    public function doStuff(): void;
}

class FooService implements Service
{
    private $a;

    public function __construct(A $a)
    {
        $this->a = $a;
    }

    public function doStuff(): void
    {
    }
}

class BarService implements Service
{
    public function doStuff(): void
    {
    }
}

class Controller
{
    private $bero;

    public function __construct(Bero $bero)
    {
        $this->bero = $bero;
    }

    public function run(bool $flag)
    {
        if ($flag) {
            $service = $this->bero->getObject(FooService::class);
        } else {
            $service = $this->bero->getObject(BarService::class);
        }
        $service->doStuff();
    }
}

$bero->addObject(Bero::class, $bero); // addObject(A::class, $a);
$c = $bero->getObject(Controller::class);
$c->run(true);
```

By adding Bero to itself we can ask for the Bero instance further down in the application &amp; retain all previously constructed class instances &amp; access them, thus class instance field `$a` for `FooService` will be the same as the global class instance `$a` &amp; not a newly created instance.

License
-------

[](#license)

Bero is released under the MIT License. See the bundled file LICENSE.txt.

###  Health Score

26

—

LowBetter than 43% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity18

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 96.8% 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 ~199 days

Total

4

Last Release

1699d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/4140f6d5a37850bd48a8801b6764ed5d096de24b12a3443f33a2c303f1a8bc98?d=identicon)[tored](/maintainers/tored)

---

Top Contributors

[![tored](https://avatars.githubusercontent.com/u/363750?v=4)](https://github.com/tored "tored (30 commits)")[![pcrov](https://avatars.githubusercontent.com/u/8586747?v=4)](https://github.com/pcrov "pcrov (1 commits)")

---

Tags

dependency-injectionphp

### Embed Badge

![Health badge](/badges/paket-bero/health.svg)

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

###  Alternatives

[pimple/pimple

Pimple, a simple Dependency Injection Container

2.7k130.5M1.4k](/packages/pimple-pimple)[neos/flow

Flow Application Framework

862.0M449](/packages/neos-flow)[api-platform/state

API Platform state interfaces

223.4M57](/packages/api-platform-state)[internal/dload

Downloads binaries.

98142.7k10](/packages/internal-dload)[symfony/json-streamer

Provides powerful methods to read/write data structures from/into JSON streams.

14440.0k8](/packages/symfony-json-streamer)[rubix/server

Deploy your Rubix ML models to production with scalable stand-alone inference servers.

632.3k](/packages/rubix-server)

PHPackages © 2026

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