symfony /
dependency-injection
Allows you to standardize and centralize the way objects are constructed in your application
91/100 healthLoading repository data…
lucatume / repository
The dependency injection container for streamlined WordPress development. Easily manage and inject dependencies for efficient and hassle-free app creation.
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
A PHP 5.6+ compatible dependency injection container inspired by Laravel IOC and Pimple that works even better on newer version of PHP.
A quick overview of the Container features:
App::get($service)->doStuff()? The App facade allows using the DI Container as
a globally available Service Locator.callback and instance to easily be integrated with
Event-driven frameworks like WordPress that require hooking callbacks to events.getIn the application bootstrap file we define how the components will come together:
<?php
/**
* The application bootstrap file: here the container is provided the minimal set of instructions
* required to set up the application objects.
*/
namespace lucatume\DI52\Example1;
use lucatume\DI52\App;
use lucatume\DI52\Container;
require_once __DIR__ . '/vendor/autoload.php';
// Start by building an instance of the DI container.
$container = new Container();
// When an instance of `TemplateInterface` is required, build and return an instance
// of `PlainPHPTemplate`; build at most once (singleton).
$container->singleton(
TemplateInterface::class,
static function () {
return new PlainPHPTemplate(__DIR__ . '/templates');
}
);
// The default application Repository is the Posts one.
// When a class needs an instance of the `RepositoryInterface`, then
// return an instance of the `PostsRepository` class.
$container->bind(RepositoryInterface::class, PostsRepository::class);
// But the Users page should use the Users repository.
$container->when(UsersPageRequest::class)
->needs(RepositoryInterface::class)
->give(UsersRepository::class);
// Bind primitive values, e.g. public function __construct( int $per_page ) {}
$container->when(UsersPageRequest::class)
->needs('$per_page')
->give(10);
// Fetch the above class without any further definitions
$container->get(UsersPageRequest::class)
// The `UsersRepository` will require a `DbConnection` instance, that
// should be built at most once (singleton).
$container->singleton(DbConnection::class);
// Set the routes.
$container->bind('home', HomePageRequest::class);
$container->bind('users', UsersPageRequest::class);
// Make the container globally available as a service locator using the App.
App::setContainer($container);
In the application entrypoint, the index.php file, we'll lazily resolve the whole dependency tree following the
rules set in the bootstrap file:
<?php
use lucatume\DI52\App;
require_once __DIR__ . '/../../vendor/autoload.php';
require_once __DIR__ . '/bootstrap.php';
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$route = basename(basename($path, '.php'), '.html') ?: 'home';
App::get($route)->serve(); ?>
?>
That's it.
Use Composer to require the library:
composer require lucatume/di52
Include the Composer autoload file in your project entry point and create a new instance of the container to start using it:
<?php
require_once 'vendor/autoload.php';
$container = new lucatume\DI52\Container();
$container->singleton(DbInterface::class, MySqlDb::class);
If you would prefer using the Dependency Injection Container as a globally-available Service Locator, then you
can use the lucatume\DI52\App:
<?php
require_once 'vendor/autoload.php';
lucatume\DI52\App::singleton(DbInterface::class, MySqlDb::class);
See the example above for more usage examples.
The main change introduced by version 3.0.0 of the library is dropping compatibility with PHP 5.2 to require a minimum
version of PHP 5.6. The library is tested up to PHP 8.1.
If you're using version 2 of DI52 in your project, then there should be nothing you need to do.
The new, namespaced, classes of version 3 are aliased to their version 2 correspondent, e.g. tad_DI52_Container is
aliased to lucatume\DI52\Container and tad_DI52_ServiceProvider is aliased to lucatume\DI52\ServiceProvider.
I suggest an update for a small performance gain, though, to use the new, namespaced, class names in place of the PHP 5.2 compatible ones:
tad_DI52_Container with lucatume\DI52\Containertad_DI52_ServiceProvider with lucatume\DI52\ServiceProviderThe new version implemented PSR-11 compatibility and the main method to get hold
of an object instance from the container changed from make to get.
Do not worry, the lucatume\DI52\Container::make method is still there: it's just an alias of
the lucatume\DI52\Container::get one.
For another small performance gain replace uses of tad_DI52_Container::make with lucatume\DI52\Container::get.
That should be all of it.
Version 3.3.0 of the library removed the aliases.php file, which previously helped to load non-PSR namespaced class names.
However, if you're using the tad_DI52_Container and tad_DI52_ServiceProvider classes in your project, you can set up the aliases by adding a few lines of code to your project's bootstrap file to ensure your code continues to work as expected:
<?php
$aliases = [
['lucatume\DI52\Container', 'tad_DI52_Container'],
['lucatume\DI52\ServiceProvider', 'tad_DI52_ServiceProvider']
];
foreach ($aliases as list($class, $alias)) {
if (!class_exists($alias)) {
class_alias($class, $alias);
}
}
A Dependency Injection (DI) Container is a tool meant to make dependency injection possible and easy to manage. Dependencies are specified by a class constructor method via type-hinting:
class A {
private $b;
private $c;
public function __construct(B $b, C $c){
$this->b = $b;
$this->c = $c;
}
}
Any instance of class A depends on implementations of the B and C classes.
The "injection" happens when class A dependencies are passed to it, "injected" in its constructor method, in place of
being created inside the class itself.
$a = new A(new B(), new C());
The flexibility of type hinting allows injecting into A not just instances of B and C but instances of any class
extending the two:
class ExtendedB extends B {}
class ExtendedC extends C {}
$a = new a(new ExtendedB(), new ExtendedC());
PHP allows type hinting not just concrete implementations (classes) but interfaces too:
class A {
private $b;
private $c;
public function __construct(BInterface $b, CInterface $c){
$this->b = $b;
$this->c = $c;
}
}
This extends the possibilities of dependency injection even further and avoids strict coupling of the code:
class B implements BInterface {}
class C implements CInterface {}
$a = new a(new B(), new C());
The B and C classes are concrete (i.e. instantiable) implementations of interfaces. The interfaces may
never change, but the implementations can and should change over the life of the code.
That's the Dependency Inversion principle: "depend upon
abstractions, non concretions".
If the implementation of BInterface changes from B to BetterB then I'd have to update all the code where I'm
building instances of A to use BetterB in place of B:
// before
$a = new A(new B(), new C());
//after
$a = new A(new BetterB(), new C());
On smaller code-bases this might prove to be a quick solution but, as the code grows, it will become less and less an applicable solution. Adding classes to the mix proves the point when dependencies start to stack:
class D implements DInterface{
public function __construct(AInterface $a, CInterface $c){}
}
class E {
public function __construct(DInterface $d){}
}
$a = new A (new BetterB(), new C());
$d = new D($a, $c);
$e = new E($d);
Another issue with this approach is that classes have to be built immediately to be injected, see $a and $d above to
feed $e, with the immediate cost of "eager" instantiation, if $e is never used than the effort put into building it,
in terms of time and resources spent by PHP to build $a, $b, $c, $d and finally $e, are wasted.
A dependency injection container will take care of building only objects that are needed taking care of
resolving nested dependencies.
Need an instance of
E? I will build instances ofBandCto build an instance ofAto build an instance ofDto finally build and return an instance ofE.
The Service Locator is a design pattern: a central place your code can ask for the s
Selected from shared topics, language and repository description—not editorial ratings.
symfony /
Allows you to standardize and centralize the way objects are constructed in your application
91/100 healthPHP-DI /
The dependency injection container for humans
89/100 healthtomphp /
Configure your application and the Dependency Injection Container (DIC) via config arrays or config files.
vipblogger /
This is a wrapper for the Bitrix24 PHP SDK. Allows you to use Bitrix through Dependency Injection.
38/100 healthyuriteixeira /
An example of what an API written in PHP without using any library or framework (but with OOP, URI routing in the code, dependency injection and friends) would look like.
18/100 healthchubbyphp /
Doctrine service factories for the laminas/laminas-servicemanager and any other dependency injection container who's been able to handle it's config, like chubbyphp/chubbyphp-container via chubbyphp/chubbyphp-laminas-config and many (Aura.Di, Pimple, Auryn, Symfony, PHP-DI) more.
72/100 health