Auto injecting dependencies in PHP objects


I must admit I don’t really know what’s the correct title for this post. Finally I use “Auto injecting dependencies in PHP objects”. I know it isn’t very descriptive. Let me explain it a little bit. This time I want to automate the Hollywood Principle (“Don’t call us, we’ll call you”). The idea is simple. Imagine one “controller”

class Controller
{
    public function hi($name)
    {
        return "Hi $name";
    }
}

We can easily automate the “hi” action

$controller = new Controller();
echo $controller->hi("Gonzalo");

Or maybe if we are building a framework and our class name and action name depends on user-input:

$class = "Controller";
$action = "hi";
$arguments = ['name' => "Gonzalo"];

echo call_user_function_array([new $class, $action], arguments);

But imagine that we want to allow something like that:

class Controller
{
    public function hi($name, Request $request)
    {
        return "Hi $name " .$request->get('surname');
    }
}

Now we need to inject Request object within our action “hi”, but not always. Only when user set a input variable with the type “Request”. Imagine that we also want to allow this kind of injection in the constructor too. We can need to use Reflection to create our instance and to call our action. Sometimes I need to work with custom frameworks and legacy PHP applications. I’ve done it in a couple of projects, but now I want to create a library to automate this operation.

The idea is to use a Dependency Injection Container (Pimple in my example) and retrieve the dependency from container (if it’s available). I cannot use “new” keyword to create the instance and also I cannot call directly the action.

One usage example is:

class Foo
{
    public function hi($name)
    {
        return "Hi $name";
    }
}

class Another
{
    public function bye($name)
    {
        return "Bye $name";
    }
}

class Bar
{
    private $foo;

    public function __construct(Foo $foo, $surname = null)
    {
        $this->foo     = $foo;
        $this->surname = $surname;
    }

    public function hi(Another $another, $name)
    {
        return $this->foo->hi($name . " " . $this->surname) . ' ' . $another->bye($name);
    }
}

$container = new Pimple();
$container['name'] = "Gonzalo2";

$builder = new G\Builder($container);

$bar = $builder->create('Bar', ['surname' => 'Ayuso']);
var_dump($builder->call([$bar, 'hi']));

var_dump($bar->hi(new Another(), 'xxxxx'));

Our library tries to retrieve the dependecy from the DIC. If it cannot do it, it creates the a new instance.
The whole “magic” is in the Builder class. You can see the library in my github account.

About these ads

About Gonzalo Ayuso

Web Architect specialized in Open Source technologies. PHP, Python, JQuery, Dojo, PostgreSQL, CouchDB and node.js but always learning.

Posted on March 3, 2014, in Dependency Injection, php, Symfony and tagged , , , . Bookmark the permalink. 6 Comments.

  1. Hi Gonzalo:

    Thanks for the article. I just wanted to point out that in a pure and perfect Object Oriented Design/Development we should Depend upon Abstractions not upon concretions (according to SOLID principles).

    I’d put a couple of interfaces and/or abstract classes to demonstrate the Dependency Injection rather than using concrete classes.

  1. Pingback: Gonzalo Ayuso: Auto injecting dependencies in PHP objects | htaccess

  2. Pingback: Gonzalo Ayuso: Auto injecting dependencies in PHP objects | facebooklikes

  3. Pingback: Дайджест интересных новостей и материалов из мира PHP № 37 (24 февраля — 9 марта 2014) » CreativLabs

  4. Pingback: Дайджест интересных новостей и материалов из мира PHP № 37 (24 февраля — 9 марта 2014) | Вести3.ру — Информационный журнал

  5. Pingback: Autoinjeção de dependências em objetos PHP |

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 1,003 other followers

%d bloggers like this: