Dependency Injection (DI/IoC) Frameworks

I have been doing some searching for DI frameworks in PHP5. I have found some forum threads, articles and blog posts regarding the following frameworks:

PicoContainer
Garden
Phemto

Pico is a Java DI framework that apparently has been ported to PHP but development on it may not be active (please inform). I cannot find a link to read more about Garden or download the core. Phemto only supports constructor injection (setter injection helps prevent circular dependency and is therefore necessary).

I am also learning CakePHP and really enjoying it because it is an event driven MVC framework (with what appears to be built in ORM support!). I would like to use CakePHP and some reliable dependency injection framework for all of my PHP5 applications. Can anyone here help me to that extent?

Thanks,
Aaron Roberson

Hi Aaron, welcome to the forums!

What exactly do you understand under DI framework and what are you expecting from it? We’ve had numerous threads on DI here in the PAD forum. If I’m not mistaken, the common opinion was that Java-alike solutions are overkill in php because of its dynamic nature.

In ColdFusion, another dynamic language, I use ColdSpring (a port of Java’s Spring) and/or LightWire (a minimalist approach to DI).

What I have in mind is basically a bean factory where I can declare all of my singletons and transient objects in one place and for them to be cached. Then, instead of invoking or instantiating the same object in several places throughout my app, I can just refer to the cached object.

The most important aspect of DI that I definitely cannot live without and is fitting for PHP as well as any other OOP app is the ability to setter and constructor inject properties and objects into singletons in the same place I declare all of my singletons.

I used to inject dependent properties and objects into other objects manually where needed but then I ended up with similar code in dissimilar places. Being able to declare my singletons and transients and then inject dependencies all in one place makes for better modularity and easier maintenance.

I agree that some Java-like solutions may be overkill for PHP because of its dynamic nature, but DI is a design pattern that is common (and necessary) to all OOP applications regardless of language and whether it is static or dynamic.

The DI topic is discussed really often here, check for example one of the recent threads

If you feel you have something to contribute, ask mods to move your thread to PDA. This doesn’t belong to the regular php forum.

I am talking about is this:

And looking for something like this:

And this:
http://www.sitepoint.com/forums/showpost.php?p=3472934&postcount=29

Without setter injection, you need to avoid circular dependencies. As such, setter injection is more powerful than constructor injection. However, in PHP, you’d want to avoid circular dependencies for another reason; PHP doesn’t have garbage collection – instead it has reference counting. This memory management scheme is prone to circular dependencies (Eg. the objects won’t get reclaimed, because they refer each other).

That is absolutely correct Kyber, that is why I have only glanced at Phemto and not spent much time on it - Phemto only supports constructor injection.

Being a ColdFusion programmer and looking at PHP code is a bit of a challenge at first, but I’m sure that a PHP programmer could look at ColdFusion code and understand what is going on much more readily. Having said that, please take a look at a ColdFusion DI framework I love and have used in multiple projects called LightWire (lightwire.riaforge.org). I bet you could port the entire thing to PHP in a couple hours or less, it is only about 350 lines of code.

To work off your example from http://www.sitepoint.com/forums/showpost.php?p=3472934&postcount=29

You would do something like this:


class DatabaseConnection
{
// ...
}

class UserGateway
{
  protected $db;

  function __construct() {

  }

  function setDBConnect($db) {
   $this->db = $db;
  }

} 

Then your factory would do something like this:


class Assembler
{
  function createUserGateway() {
      $userGateway = new userGateway();
      $userGateway.setDBConnect(createDatabaseConnection()); //syntax is wrong, but I hope you see I'm calling the setDBConnect() method on the userGateway object and passing in the databaseConection object
      return $userGateway;
  }

  function createProductGateway() {
      $productGateway = new ProductGateway();
      $productGateway.setDBConnect(createDatabaseConnection()); //syntax is wrong, I know
      return $productGateway;
  }

  function createDatabaseConnection() {
    return new DatabaseConnection();
  }

} 

Then you would want to add the registry so that objects are only created once. Finally, what I would like is to be able to abstract that out into a container so that all of this can be done in one place.

I don’t really think a configuration approach is worth the effort – at least in PHP. Containers such as Phemto use reflection and interfaces as a form of configuration. If you consider typehints a benefit in PHP (There are certainly mixed opinions about that), the configuration follows “for free”, and so is perhaps worth it. This approach can only handle object dependencies (you can’t pass configuration data, such as a database-login &c), and it’s limited to use constructor injection. As I mentioned though, I think it’s quite rare that you’d need setter injection in PHP, since circular dependencies should be avoided for other reasons.

I guess this is where my PHP knowledge comes short, though I don’t see why there would be any difference when were still talking about dynamic languages and OOP.

It would be nice to just do the following:


registerSingleton("firstClassName:);
injectProperty("someValue");
injectSetterDependency("secondClassName","FirstClassName");

registerTransient("secondClassName:);
injectProperty("someValue");
injectSetterDependency("firstClassName","secondClassName");

You could even programatically loop over the definitions which would minimize the effect of configuration.

Just to be sure, is this the problem?


class Foo {
    __construct(Bar $bar) {
        $this->_bar = $bar;
    }
}
class Bar {
    __construct(Quark $quark) {
        $this->_quark = $quark;
    }
}
class Quark {
    __construct(Foo $foo) {
        $this->_foo = $foo;
    }
}

If so, would a new Phemto feature give you what you want:


class Quark {
    function setByPhemto(Foo $foo) {
         $this->_foo = $foo;
     }    
 }

$injector->register('Foo');
$injector->register('Bar');
 $injector->registerForSetterInjection('Quark');
 

Phemto could call a setter-injector method (Quark::setByPhemto) after instantiating any Quark objects, using type hints as usual to fill dependencies.

Without trying to find the precise situation ou wish to resolve here, the big difference is that in PHP you can do things like these:

$newClassName = someFunctionOrMethodThatReturnsTheClassNameINeed();

$object = $newClassName();

$object->$anotherVariableHoldingTheNameOfTheProperty = 'a new value':

$object->aNewPropertyNotDefinedInTheClass = 'blabla'

Don’t also forget that a variable (or class attribute) can hold a value of any type. And of course there are things like __set(), __get() and __call() which gives you a whole new set of possibilities in dynamically injecting dependencies etc.

That would work McGruff. How do you actually tell Phemto to inject Foo into Quark? It looks like you registered all three, but as far as I can tell nothing is telling Foo or Bar to be injected into Quark in your code.

As I’ve been delving more and more into PHP5 and OOP I think I am learning why the folks here may not find DI frameworks as useful and necessary as OO developers in other languages. At least from looking at CakePHP and CodeIgnitor it appears that PHP developers have no problem coupling their model with other aspects of their application (i.e. framework specific code in the model). This leads me to think that in the PHP community there is no general understanding that the model should be decoupled from the rest of the app.

In my OO experience I am used to separating the model into a tableGateway, DAO, Service (when not using the ActiveRecord pattern) and business object layer. I inject my tableGateway and DAO into my Service layer. I also inject my databaseConnection object into my tableGateway and DAO.

My tableGateway handles multiple record and filtered queries. My DAO handles basic CRUD operations. The business object is just a dumb object that has getters and setters (accessors and mutators) for each field in the database table as well as some smart getters. The Service layer is the API to all of these other layers so I would call something like service->saveObject() and service->deleteObject() or service->getObject().

In a domain centric application my tableGateway, DAO, Service and Business object pretty much map to one table in the database. That means that I have a tableGateway, DAO, Service and Business object for pretty much every table in my database.

In all of my poking around trying to figure out how this would all port to PHP, I have not found anything in the PHP community that resembles this kind of setup.

Perhaps this has something to do with the disconnect between PHP and DI frameworks.

Sorry I didn’t make myself clear. Phemto doesn’t do this at the moment: I was thinking out loud as to how this might work if the feature were added. Phemto would need to be told that a particular object needs some stuff passed in after the object is instantiated rather than via the constructor. Type hints in a setter method could specify what.

I’d be interested in working on this if the project developers think it’s worth adding.

As I’ve been delving more and more into PHP5 and OOP I think I am learning why the folks here may not find DI frameworks as useful and necessary as OO developers in other languages
I think a dependency injection container like Phemto is an essential tool for php. It’s really nice if you need to make some kind of behaviour configurable. If not, I’d just wire everything up with some hard-coded factories.

I realized that, I was only trying to clarify things on my side.

Even in a small project I have found a DI framework to be the best approach, definitely over having several factories.

Don’t forget one important thing: in PHP there is no such thing as in-memory persistence. Each HTTP call is a new script run, and all data gathering (database calls, file loadings etc) have to be done again. In Java, you have the option to load as many objects as your server’s memory allows and keep them there – saving and updating them as necessary – for as long as you like. PHP is very different in that aspect, so some things that are preferable in Java and other languages simply don’t work here.

The injector that I use looks pretty much like the following, which I needed after using Grails for all of about 30 minutes ;).


public function inject($object);
	$robj = new ReflectionObject($object);
	$properties = $robj->getProperties();
	foreach ($properties as $propertyObject) {
		$name = $propertyObject->getName();
		$name = ucfirst($name);
		if (Zend_Registry::isRegistered($name)) {
			$propertyObject->setValue($object, Zend_Registry::get($name));
		}
	}
}

The service objects themselves are read from a specific location in the webapp (a directory), and I have some separate code that allows for non-managed value configuration and the actual registration of services. It’s a simple step of

  • Create the services and register them in a registry
  • execute the above code to inject them with the other services

I use that for both my controllers and service objects so I’m not needing getters and setters everywhere. A simple example of use is



class DbService
{

}

class MyService 
{
	public $dbService;
	
	public function getSomeData()
	{
		$this->dbService->fetchObjects();
	}
}

class MyActionController
{
	public $myService;
	
	public function indexAction()
	{
		$this->view->data = $this->myService->getSomeData();
	}
}

You might also want to try Ding (marcelog Ding: PHP Dependency Injection, inversion of control, and Aspect Oriented Programming Framework), a dependency injection and inversion of control container modeled after Spring™ for Java, supports JSR 250/330 annotations, xml and yaml as bean definitions, has AOP support and MVC implementation.

Regards!

I can recommend Yadif if you’re happy to use a simple wiring file:

You might want to take a look at Symfony’s “standalone” dependency injector - although it relies on other Sym libs to parse config files:
Symfony Dependency Injection - Reinventing how you manage PHP classes

There’s also Aura.di - a new package by the author of the Solar framework: https://github.com/auraphp/aura.di

I cannot stress highly enough how useful a dependency injector is in the context of a non-trivial application.