romchik38 / php-container
PSR-11: Container interface
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/romchik38/php-container
Requires
- php: >=8.3
- psr/container: ^2.0
Requires (Dev)
- laminas/laminas-coding-standard: ^3.0
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^11.1
README
status: ready to use
phpstan: level 8
phpunit: full
The Container helps configure an application. The implementation is compatible with PSR-11 ContainerInterface.
Main features:
- stores values as is (primitive, objects etc).
- creates a shared object (singleton).
- creates a fresh copy of the same class on each call.
- multi ability to create a different instance of the same class by provided keys.
- link a key to another key
- promises - container creates an instance only on a
getcall, to avoid unused creations. - can detect a circular dependency
- can be in lazy mode
Latest version
see changelog
Install
composer install romchik38/php-container
Quick examples
Primitive
Primitive class is responsible to hold a static mixed value. Use method add to store it.
$container = new \Romchik38\Container\Container(); $container->add('some key', 'any string'); $container->add('config', ['key' => 0]); $container->add('important_object', new ImportantClass()); // somewhere in the code $str = $container->get('some key'); // ...etc
Shared
Shared class is responsible to create only one instance of concrete class and returns it on each get request. Use method shared there.
$container = new \Romchik38\Container\Container(); $container->shared( '\Classes\Primitive1', // class name [7] // params, number 7 in this case ); // $shared1 and $shared2 are the same $shared1 = $container->get('\Classes\Primitive1'); $shared2 = $container->get('\Classes\Primitive1');
Fresh
Fresh class is responsible to create a new instance of concrete class on each get request. Use method fresh of the container.
$container = new \Romchik38\Container\Container(); $container->fresh( '\Classes\Primitive1', // class name [7] // params, number 7 in this case ); // $fresh1 and $fresh2 are defferent objects that hold the same number 7 $fresh1 = $container->get('\Classes\Primitive1'); $fresh2 = $container->get('\Classes\Primitive1');
Multi
Multi class is responsible to create a new (or shared) copy of a concrete class with a given key. It maght be usefull when dealing with interfaces or creating a few same classes with different configuration. Use method multi.
// Interface example $container = new \Romchik38\Container\Container(); $container->multi( '\DB\DatabaseUseSql', '\DatabaseInterface', true, // true - shared, false - fresh ['dsn:localhost'] // params ); $database = $container->get('\DatabaseInterface');
Link
Link class helps to connect one key with another key. Use method link to store it. You can also make a reference to the class. This can be useful when using Interfaces.
$container = new \Romchik38\Container\Container(); $container->add('some key', 'any string'); $container->link('another key', 'some key'); // somewhere in the code $str = $container->get('another key'); // $str holds 'any string'
Promises
Promise is responsible to defer a creation of the class's dependency. It used when a class has another class as a dependency.
Promises can be used with methods shared, fresh and multi.
$container = new \Romchik38\Container\Container(); $container->shared( '\DB\Database', [ 'db:mysql', // first param as a string new Promise('\SomeConnection'), // second param as a promise ] );
In the example above, we promise to add a class \SomeConnection to the container. \SomeConnection is a class name, but it can be any key, used with multi method. In other words we pass a container key as a param.
Do not forget to add a \SomeConnection
$container->fresh( '\SomeConnection', // class name [] // params, in that case is nothing );
Circular dependency detection
We can primise to add the first class to another, and a the second class to the first and so on. Promise chain can be as long as you want. But if you try to add a class as a promise which depends on any early promised classes an exception will be thrown.
$container = new \Romchik38\Container\Container(); $container->shared( '\ClassA1', [new Promise('\ClassA2')] ); $container->shared( '\ClassA2', [new Promise('\ClassA1')] ); // Exception there
Data Replacement
Currently, it is only possible to override data for Primitives that are added with the add method. An attempt to replace data using other methods will throws an error ContainerException.
$id = 'key'; $container = new \Romchik38\Container\Container(); $container->add($id, 'value'); $container->add($id, 'value2'); $value = $container->get($id); // value2
Lazy mode
$container = new \Romchik38\Container\Container(true); $container->shared('\Classes\Primitive1', [7]); // $shared1 is not initialized $shared1 = $container->get('\Classes\Primitive1'); // $shared is initialized, because access on property numb which holds 7 $shared1->numb;
Code quality
- phpstan level 8
- phpunit
- laminas-coding-standard
Projects that use this product
The PHP container was used to build the bootstrap system in the following projects:
- Site1
- Site2
Site1
Site1 is a simple website — that demonstrates a multi-page site with a login system, a sitemap, Google reCAPTCHA, and email-based password recovery. See source code on github page.
Also available Live Site1 preview.
Site2
Site2 is a more complex version of the site1 with more functionality. It demonstrates a multilanguage system, twig view, Image Converter and other features. See source code on github page.
Also available Live Site2 preview.