Skip to main content

Introducing Bucket: A Minimal Dependency Injection Container for PHP

Share:

Free JavaScript Book!

Write powerful, clean and maintainable JavaScript.

RRP $11.95

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.

New books out now!

Learn how Git works, and how to use it to streamline your workflow!


Google, Netflix and ILM are Python users. Maybe you should too?