I got fed up with the lack of a decent DI-container for PHP, so today I created Bucket. To be clear, what I think is wrong with the currently available containers (at least that I’m aware of) is that they either are unstable, abandoned, require a lot of up-front configuration in external XML-files, or are tightly integrated into some full-stack framework. I had my hopes up for Phemto for a while, but it seems that progress has stalled.
Bucket doesn’t do much, but that is actually the intention. It means that it is feature-complete and probably bug free. And unlike Twittee, it is actually useful as-is.
Bucket is mostly a wrap-up of the code I described a bout a year back in Dealing with Dependencies. It adds a few additional features out-of-the-box. Notably:
Default factory uses reflection/typehints to determine dependencies. So you can go:
class Foo {
}
class Bar {
function __construct(Foo $foo) {}
}
$container = new bucket_Container();
$container->get('Bar');
And with interfaces:
interface Zap {
}
class Foo implements Zap {
}
class Bar {
function __construct(Zap $zap) {}
}
$container = new bucket_Container();
$container->registerImplementation('Zap', 'Foo');
$container->get('Bar');
You can use callbacks for factories. Not that useful right now, but when PHP 5.3 (hopefully very soon) sees the light of day, you can use:
$bucket = new bucket_Container(
array(
'pdo' => function($container) {
return new PDO("mysql:host=localhost;dbname=addressbook", "root", "secret");
}
)
);
You can also use a class based factory. This can be combined with callbacks, for overriding methods. Eg. if you create a callback, it takes precedence over the class method. Until 5.3, you’d probably want to write factories as class methods:
class MyFactory {
function new_pdo($container) {
return new PDO("mysql:host=localhost;dbname=addressbook", "root", "secret");
}
}
$bucket = new bucket_Container(new MyFactory());
Support for child scopes. Means that you can create a local container that doesn’t leak state to its parent. Probably not the most important feature for standard web applications, but a nice feature for longer running scripts. Usage is:
$container = new bucket_Container();
$scope = $container->makeChildContainer();
It’s just 153 lines of code, with no external requirements, so go on and grab your copy at: http://github.com/troelskn/bucket/tree/master
Troels has been crafting web applications, as a freelancer and while employed by companies of various sizes, since around the time of the IT-bubble burst. Nowadays, he's working on backend systems for a Danish ISP. In his spare time, he develops and maintains Konstrukt, a web application framework for PHP, and is the organizer of a monthly PHP-meetup in Copenhagen.