PHPackages                             lss/yacontainer - 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. lss/yacontainer

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

lss/yacontainer
===============

Lightweight Dependency Injection Container

3.0(4y ago)469MITPHPPHP &gt;=8.1CI failing

Since Jun 23Pushed 4y ago1 watchersCompare

[ Source](https://github.com/pavarnos/YAContainer)[ Packagist](https://packagist.org/packages/lss/yacontainer)[ Docs](https://github.com/pavarnos/YAContainer)[ RSS](/packages/lss-yacontainer/feed)WikiDiscussions master Synced 2w ago

READMEChangelog (7)Dependencies (4)Versions (8)Used By (0)

YAContainer: Yet Another Container
==================================

[](#yacontainer-yet-another-container)

A minimal Dependency Injection Container for PHP 8.1+

The goals of this project are

- Storage for objects by class name only: call `get(MyCleverThing::class)`
- Magic: auto-loading / auto-configuration with a minimum of fuss.
- Minimalism: No compilation, minimal declaration / configuration in advance, as little code as possible, only the barest necessary features.
- Performance: Strips out all but essential features.
- Strictly typed: uses phpstan @template so that if you get(T::class) it knows you will receive an object of type T back
- Suitable for larger projects or monolithic applications with a lot of classes but only a few used per request.
- 100% test coverage

This package (or earlier versions of it) have been used in production on many sites for over a decade now. No fuss. It just works.

Why another container when there are already so many that are very good?

- [Symfony Dependency Injection](http://symfony.com/doc/current/components/dependency_injection.html) needs up front declaration in xml, yml or php. It is possible to compile and dump the built container into a PHP class. For large projects, generation, compilation and dump can take a few seconds and needs to be re-done after every small change.
- [PHP-DI](http://php-di.org/) is flexible and powerful with excellent support from the lead maintainer. The documentation is nice. [Benchmarks](https://www.sitepoint.com/php-dependency-injection-container-performance-benchmarks/) show it is slower than others (though the benchmarks are from 2014).
- [Auryn](https://github.com/rdlowrey/auryn) is clean and simple with clever reflection caching and magic autoloading. It deliberately does not follow PSR-11. Informal googling suggests there is [little](https://github.com/brainfoolong/php-reflection-performance-tests) [benefit](http://stackoverflow.com/a/24648651/117647) from caching ReflectionClass.
- [Aura.DI](https://github.com/auraphp/Aura.Di) needs up front configuration of every class.
- [Pimple](http://pimple.sensiolabs.org/) is tiny, elegant, and works well for small projects. It needs everything declared up front.

Pull requests welcome, but bear in mind the above project goals. If you have more complex needs, the other (better written, better supported, more mature) projects mentioned above will be a better choice for you.

How to use
==========

[](#how-to-use)

Create your container and pass in scalar values and aliases to the constructor eg

```
$aliases = [
    MyFoo::class => MyCachedFoo::class,
    MyBarInterface::class => MyBarImplementation::class
];
$container = new Container($_ENV, $aliases);
```

This is the quickest way to set up your container with static configuration.

Ask the container for any autoloaded class by name eg `$container->get(My\\Namespace\\MyClass::class);`. The container will automatically build dependencies in the constructor and any recursive dependencies in *their* constructors. For most classes this should work with no further effort. For other classes that need extra configuration, you can use aliases, scalar injection and factory methods.

Aliases
-------

[](#aliases)

Constructors should usually depend on interfaces rather than concrete classes. So how do you tell the container which concrete class to use? Specify an alias as in the above example.

Scalar injection / Parameters
-----------------------------

[](#scalar-injection--parameters)

Scalar values (int,string,float,bool) can be used as constructor or setter parameters if the name matches *exactly* (case sensitive) and a default value is not provided.

```
class DatabaseConnection extends \PDO {
    public function __construct(string $databaseDSN, string $databaseUser, string $databasePassword)
    {
        $options = ['charset' => 'utf8',PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION];
        parent::__construct($databaseDSN, $databaseUser, $databasePassword, $options);
    }

    // ... other utility functions
}

$container = new Container(['databaseDSN' => 'mysql:host=localhost;dbname=theDBName', 'databaseUser' => 'theUserName', 'databasePassword' => 'thePassword']);
$databaseConnection = $container->get(DatabaseConnection::class);
```

You can also use `$container->addScalar()` to add more later if needed.

If a default value is provided for a constructor parameter, it will be respected and the scalar value will not be injected. If you need to pass a different value, use a factory instead.

You can also use a callable for a scalar value. The callable will be called only once then replaced with its value for all subsequent uses.

```
$container->addScalar('maximumPassengers', function (Configuration $config) {
    return $config->getMaximumPassengers();
});
```

Factory methods / Callables
---------------------------

[](#factory-methods--callables)

For classes that are complicated to build or where the class needs a lot of stuff that nothing else needs, use a factory.

```
$fuelPercent = 75;
$container = new Container();
$container->addFactory(Car::class, function (EngineInterface $engine) use ($fuelPercent): Car {
    $result = new Car($engine);
    $result->refuel($fuelPercent);
    return $result;
});
```

Setter injection
----------------

[](#setter-injection)

Setter injection can be emulated via a factory method. Call your setters after

Shared instances
----------------

[](#shared-instances)

All generated objects are shared by default. This means that each call to `get()` for the same class name will return the exact same class instance each time. If you need a different instance each time, provide a function that tells the container which instances to share.

```
$container->setShouldShare(function (string $className): bool { return $className !== Car::class; });
```

will build a new `Car` class instance for each `get()` call.

To disable sharing (create a new instance for every object every time)

```
$container->setShouldShare(function (string $className): bool { return false; });
```

Forget
------

[](#forget)

If you need a shared instance most of the time, but for some special reasons occasionally need a fresh instance, use `forget()` to forget the current one. The next call to `get()` will create a fresh instance.

```
$car = $container->get(Car::class);
$container->forget(Car::class);
$aDifferentCar = $container->get(Car::class);
```

PSR-11 Containers
=================

[](#psr-11-containers)

We deliberately do not implement Psr\\Container\\ContainerInterface because

- PSR-11 is not strict enough. It is a generic dictionary designed to hold any mixed thing keyed by any string
- A number of packages use v1.0 or v2.0 and managing cross dependencies was getting tricky. One fewer dependency is helpful.
- Wrapping this container in a PSR-11 proxy is trivial: see below

```
class Psr11ContainerException extends \InvalidArgumentException implements Psr\Container\ContainerExceptionInterface {}

class Psr11Container implements Psr\Container\ContainerInterface {
    public __construct(private LSS\Container $wrapped) {}

    public function get(string $id) {
        try {
            return $this->wrapped->get($id);
        } catch (\Throwable $ex) {
            throw new Psr11ContainerException('Cannot build ' . $id, 0, $ex);
        }
    }

    public function has(string $id): bool
    {
        return $this->wrapped->has($id);
    }
}
```

This is NOT a Service Locator
=============================

[](#this-is-not-a-service-locator)

Avoid the temptation to pass the container as a dependency to your created classes. The best way to use this is in your bootstrap code to build the parts of your application into a single unit. [Auryn has a good example](https://github.com/rdlowrey/auryn#app-bootstrapping).

###  Health Score

32

—

LowBetter than 69% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity13

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity73

Established project with proven stability

 Bus Factor1

Top contributor holds 95.5% 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 ~159 days

Recently: every ~108 days

Total

7

Last Release

1606d ago

Major Versions

1.2 → 2.02021-08-03

2.0 → 3.02022-02-05

PHP version history (4 changes)v1.0.0PHP ~7.1

1.1.0PHP &gt;=7.1|^8.0

2.0PHP &gt;=8.0

3.0PHP &gt;=8.1

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/589595?v=4)[Steve Pavarno](/maintainers/pavarnos)[@pavarnos](https://github.com/pavarnos)

---

Top Contributors

[![pavarnos](https://avatars.githubusercontent.com/u/589595?v=4)](https://github.com/pavarnos "pavarnos (21 commits)")[![stof](https://avatars.githubusercontent.com/u/439401?v=4)](https://github.com/stof "stof (1 commits)")

---

Tags

containerdependency-injectionphpcontainerdependency-injection

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/lss-yacontainer/health.svg)

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

###  Alternatives

[pimple/pimple

Pimple, a simple Dependency Injection Container

2.7k133.2M1.4k](/packages/pimple-pimple)[php-di/php-di

The dependency injection container for humans

2.8k53.2M1.2k](/packages/php-di-php-di)[aura/di

A serializable dependency injection container with constructor and setter injection, interface and trait awareness, configuration inheritance, and much more.

352982.2k60](/packages/aura-di)[acclimate/container

Provides adapters for various third-party service containers.

219394.9k15](/packages/acclimate-container)[mrclay/props-dic

Props is a simple DI container that allows retrieving values via custom property and method names

3512.4M3](/packages/mrclay-props-dic)[slince/di

A flexible dependency injection container

20268.4k6](/packages/slince-di)

PHPackages © 2026

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