tyler/envase

Tiny PHP PSR ContainerInterface Implementation

v0.1.6 2023-09-04 16:25 UTC

This package is auto-updated.

Last update: 2024-05-04 18:07:33 UTC


README

Codecov Build License Version Downloads

Very tiny PHP implementation of the PSR-11 Container.

"Envase" is Spanish for Container.

About

Envase container is extremely easy to configure and use. It features a static registry as well as the ability to resolve classes and their dependencies using autowiring. Like a lot of container implementations when you call get it will only resolve the instance the first time and any future call will return the original resolved instance.

Installation

composer require tyler/envase

Usage

Basic

// Static definitions
// simple key => val pairs
$defs = [
    'foo' => 'bar'
    'config' => [
        'dir' => '/path/to/something/'
    ],
    'Session' => new Session
];

// Create container with defs
$c = new Envase\Container($defs);

// Add additional defs
$c->set('new', 'value');

// retrieve item
$item = $c->get('foo');

// $item will equal 'bar'

Closures

So we can lazy load class instances at the time of first use you can add definitions as Closures that will be invoked the first time get is called.

$c->set('foo', fn(Envase\Container $c) => new Bar);

// or the short hand helper
$c->set('foo', Envase\get(Bar::class))

$bar = $c->get('foo'); // <-- will result in calling the closure

Note: The next time get is called for 'foo' the resolved instance will be returned

Autowiring

By default (might change later) if you ask the container for an object it will resolve all of the __construct dependencies recursively with the container. IF a constructor argument is a primitive type it will attempt to resolve it by name from the container;

class Foo 
{
    public function __construct(
        public Bar $bar,
        public string $dirToSomething
        
    )
}

class Bar
{
}

$c = new Envase\Container([
    'dirToSomething' => '/path/to/somewhere'
]);

$foo = $c->get(Foo::class);

In this case $foo will be an instance of class Foo and will have the properties $bar = instance of Bar and $dirToSomething = '/path/to/somewhere'

Injectable Properties

If a property on a class being resolved by the container has the #[Inject] attribute, the container will use that to set that properties value.

If you set this property form the constructor, Injected properties will override the constructor set

class Foo 
{
    #[Inject]
    private Bar $bar; // will auto inject instance of Bar

    #[Inject]
    private string $foo // Will auto inject key foo, value will be 'bar'

    #[Inject("fizz")]
    private string $something // Will auto inject key fizz, value will be 'buzz'
}

class Bar
{
}

$c = new Envase\Container([
    'foo' => 'bar',
    'fizz' => 'buzz'
]);

$foo = $c->get(Foo::class); // will be instance of Foo

If a key or object can't be resovled the container will throw a NotFoundException

Making objects

IF you need to make a new instance of a class you can call the containers make method. Note, this will only make a new instance of that class, all dependencies will be resolved from the container;

$foo = $c->make(Foo::class);