It is surprising that on Habré there are still no articles about this ingenious DI container for PHP.
Why ingenious? Because the entire code of this creation fits into 80 lines - a small object with great potential.
The container is a single class, and its connection to the project is as follows:
require_once '/path/to/Pimple.php';
Creating a container is just as easy:
$container = new Pimple();
Like many other DI containers, Pimple supports two types of data: services and parameters.
')
Parameters declaration
To declare parameters in Pimple is very simple: we use a container as a simple array:
Service announcement
A service is an object, a part of a system that performs its specific task.
For example, services can be: an object that provides a connection to a database, is responsible for sending mail, templating output data, etc.
In Pimple, services are defined as anonymous functions that return a service object:
Please note that the anonymous function has access to the current container and this allows other parameters or services to be used in it.
Service objects are created only when they are accessed, so the order of the declaration does not matter.
Using the services created is just as easy:
Announcement of services "Singltonov"
By default, each time Pimple is called, it returns a new service object. If one instance is required for the entire application, all you need to do is wrap the declaration in the share () method:
$container['session'] = $container->share(function ($c) { return new Session($c['session_storage']); });
Function declaration
Since Pimple treats all anonymous functions as a service declaration, to declare
the functions in the container, all you need to do is wrap the whole thing into the protect () method:
$container['random'] = $container->protect(function () { return rand(); });
Change of services after their announcement
In some cases, it may be necessary to change the behavior of the already announced service. Then you can use the extend () method to register additional code that will be executed immediately after the service is created:
$container['mail'] = function ($c) { return new \Zend_Mail(); }; $container['mail'] = $container->extend('mail', function($mail, $c) { $mail->setFrom($c['mail.default_from']); return $mail; });
The first parameter to this function is the name of the service that needs to be added, and the second is the function that takes the service object and the current container as arguments. As a result, when the service is accessed, the object returned by this function is obtained.
If the service was “Singleton”, you need to rewrap the service add-on code with the share () method, otherwise the add-ons will be called each time the service is accessed:
$container['twig'] = $container->share(function ($c) { return new Twig_Environment($c['twig.loader'], $c['twig.options']); }); $container['twig'] = $container->share($container->extend('twig', function ($twig, $c) { $twig->addExtension(new MyTwigExtension()); return $twig; }));
Access to the service return function
Each time you access a service, Pimple automatically calls its ad function. If you want to get direct access
to the declaration
function , you can use the raw () method:
$container['session'] = $container->share(function ($c) { return new Session($c['session_storage']); }); $sessionFunction = $container->raw('session');
Reuse of the finished container
If you use the same libraries from project to project, you can create ready-made containers for reuse. All you need to do is expand the Pimple class:
class SomeContainer extends Pimple { public function __construct() { $this['parameter'] = 'foo'; $this['object'] = function () { return stdClass(); }; } }
And you can easily use this finished container inside another container:
$container = new Pimple();
Conclusion
Dependency management is one of the most important and at the same time difficult tasks in developing web applications. Most frameworks offer their own solutions to this problem. However, in the case of using frameworks without a dependency manager or designing an application architecture without frameworks, I would definitely choose Pimple as a simple and small DI container.
PS Examples of use - translation of the official
Pimple readme .