Skip to main content

A Minimal Dependency Injection Container for PHP

    Share

    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