SlideShare a Scribd company logo
1 of 101
Download to read offline
Dependency Injection
with PHP 5.3

Fabien Potencier
Fabien Potencier
Serial entrepreneur
Developer by passion
Founder of Sensio
Creator and lead developer of Symfony
On Twitter @fabpot
On github http://www.github.com/fabpot
Blog http://fabien.potencier.org/
Dependency Injection

A real world Ā«Ā webĀ Ā» example
In most web applications, you need to manage the user preferences

   ā€“ā€Æ The user language
   ā€“ā€Æ Whether the user is authenticated or not
   ā€“ā€Æ The user credentials
   ā€“ā€Æ ā€¦
This can be done with a User object

   ā€“ā€Æ setLanguage(), getLanguage()
   ā€“ā€Æ setAuthenticated(), isAuthenticated()
   ā€“ā€Æ addCredential(), hasCredential()
   ā€“ā€Æ ...
The User information
         need to be persisted
        between HTTP requests

We use the PHP session for the Storage
class SessionStorage
{
  function __construct($cookieName = 'PHP_SESS_ID')
  {
    session_name($cookieName);
    session_start();
  }

    function set($key, $value)
    {
      $_SESSION[$key] = $value;
    }

    // ...
}
class User
{
  protected $storage;

    function __construct()                      Very hard to
    {                                            customize
      $this->storage = new SessionStorage();
    }

    function setLanguage($language)
    {
      $this->storage->set('language', $language);
    }

    // ...
}                           Very easy
                              to use
$user = new User();
class User
{
  protected $storage;                  Very easy to
                                        customize
    function __construct($storage)
    {
      $this->storage = $storage;
    }
}

$storage = new SessionStorage();
$user = new User($storage);
                                     Slightly more
                                     difficult to use
Thatā€™s Dependency Injection

      Nothing more
Letā€™s understand why the ļ¬rst example
is not a good idea
I want to change the session cookie name
class User
{
  protected $storage;

    function __construct()
                                                    Hardcode it in the
    {                                                   User class
      $this->storage = new SessionStorage('SESSION_ID');
    }

    function setLanguage($language)
    {
      $this->storage->set('language', $language);
    }

    // ...
}

$user = new User();
class User
{
  protected $storage;

    function __construct()
    {
        $this->storage = new SessionStorage(STORAGE_SESSION_NAME);
    }
}
                                                              Add a global
                                                             configuration?
define('STORAGE_SESSION_NAME', 'SESSION_ID');

$user = new User();
class User
{
  protected $storage;

    function __construct($sessionName)
    {
      $this->storage = new SessionStorage($sessionName);
    }
}

$user = new User('SESSION_ID');
                                         Configure via
                                             User?
class User
{
  protected $storage;

  function __construct($storageOptions)
  {
    $this->storage = new SessionStorage($storageOptions
['session_name']);

$user = new User(
   array('session_name' => 'SESSION_ID')
);
                                      Configure with an
                                            array?
I want to change the session storage implementation

                   Filesystem
                     MySQL
                   Memcached
                       ā€¦
class User
{
  protected $storage;

    function __construct()                             Use a global
    {                                                 registry object?
      $this->storage = Registry::get('session_storage');
    }
}

$storage = new SessionStorage();
Registry::set('session_storage', $storage);
$user = new User();
Now, the User depends on the Registry
Instead of harcoding
    the Storage dependency
inside the User class constructor

Inject the Storage dependency
       in the User object
class User
{
  protected $storage;

    function __construct($storage)
    {
      $this->storage = $storage;
    }
}

$storage = new SessionStorage('SESSION_ID');
$user = new User($storage);
What are the advantages?
Use diļ¬€erent Storage strategies
class User
{
  protected $storage;

    function __construct($storage)
    {
      $this->storage = $storage;
    }
}                                                   Use a different
                                                    Storage engine
$storage = new MySQLSessionStorage('SESSION_ID');
$user = new User($storage);
Conļ¬guration becomes natural
class User
{
  protected $storage;

    function __construct($storage)
    {
      $this->storage = $storage;
    }
}                                                   Configuration
                                                      is natural
$storage = new MySQLSessionStorage('SESSION_ID');
$user = new User($storage);
Wrap third-party classes (Interface / Adapter)
class User
{
  protected $storage;
                                                      Add an interface
    function __construct(SessionStorageInterface $storage)
    {
      $this->storage = $storage;
    }
}

interface SessionStorageInterface
{
  function get($key);

    function set($key, $value);
}
Mock the Storage object (for testing)
class User
{
  protected $storage;

    function __construct(SessionStorageInterface $storage)
    {
      $this->storage = $storage;
    }
}
                                                      Mock the Session
class SessionStorageForTests implements SessionStorageInterface
{
  protected $data = array();

    static function set($key, $value)
    {
      self::$data[$key] = $value;
    }
}
Use diļ¬€erent Storage strategies
       Conļ¬guration becomes natural
Wrap third-party classes (Interface / Adapter)
    Mock the Storage object (for testing)


Easy without changing the User class
Ā«Ā Dependency Injection is where
   components are given their dependencies
    through their constructors, methods, or
             directly into ļ¬elds.Ā Ā»
http://www.picocontainer.org/injection.html
$storage = new SessionStorage();

// constructor injection
$user = new User($storage);

// setter injection
$user = new User();
$user->setStorage($storage);

// property injection
$user = new User();
$user->storage = $storage;
A slightly more complex
web example
$request = new Request();
$response = new Response();

$storage = new FileSessionStorage('SESSION_ID');
$user = new User($storage);

$cache = new FileCache(
   array('dir' => dirname(__FILE__).'/cache')
);
$routing = new Routing($cache);
class Application
{
  function __construct()
  {
    $this->request = new WebRequest();
    $this->response = new WebResponse();

        $storage = new FileSessionStorage('SESSION_ID');
        $this->user = new User($storage);

        $cache = new FileCache(
           array('dir' => dirname(__FILE__).'/cache')
        );
        $this->routing = new Routing($cache);
    }
}

$application = new Application();
Back to square 1
class Application
{
  function __construct()
  {
    $this->request = new WebRequest();
    $this->response = new WebResponse();

        $storage = new FileSessionStorage('SESSION_ID');
        $this->user = new User($storage);

        $cache = new FileCache(
           array('dir' => dirname(__FILE__).'/cache')
        );
        $this->routing = new Routing($cache);
    }
}

$application = new Application();
We need a Container
     Describes objects
  and their dependencies

 Instantiates and conļ¬gures
     objects on-demand
A container
SHOULD be able to manage
  ANY PHP object (POPO)


The objects MUST not know
  that they are managed
      by a container
ā€¢ā€Æ Parameters
   ā€“ā€Æ The SessionStorageInterface implementation we want to use (the class name)
   ā€“ā€Æ The session name
ā€¢ā€Æ Objects
   ā€“ā€Æ SessionStorage
   ā€“ā€Æ User
ā€¢ā€Æ Dependencies
   ā€“ā€Æ User depends on a SessionStorageInterface implementation
Letā€™s build a simple container with PHP 5.3
DI Container

Managing parameters
class Container
{
  protected $parameters = array();

    public function setParameter($key, $value)
    {
      $this->parameters[$key] = $value;
    }

    public function getParameter($key)
    {
      return $this->parameters[$key];
    }
}
Decoupling


$container = new Container();                             Customization
$container->setParameter('session_name', 'SESSION_ID');
$container->setParameter('storage_class', 'SessionStorage');




$class = $container->getParameter('storage_class');
$sessionStorage = new $class($container->getParameter('session_name'));
$user = new User($sessionStorage);
                                                        Objects creation
class Container                            Using PHP
{                                         magic methods
  protected $parameters = array();

    public function __set($key, $value)
    {
      $this->parameters[$key] = $value;
    }

    public function __get($key)
    {
      return $this->parameters[$key];
    }
}
Interface
                                                          is cleaner


$container = new Container();
$container->session_name = 'SESSION_ID';
$container->storage_class = 'SessionStorage';

$sessionStorage = new $container->storage_class($container->session_name);
$user = new User($sessionStorage);
DI Container

Managing objects
We need a way to describe how to create objects,
    without actually instantiating anything!

      Anonymous functions to the rescue!
Anonymous Functions / Lambdas


               A lambda is a function
                   deļ¬ned on the ļ¬‚y
                    with no name

function () { echo 'Hello world!'; };
Anonymous Functions / Lambdas

                A lambda can be stored
                      in a variable

$hello = function () { echo 'Hello world!'; };
Anonymous Functions / Lambdas

                And then it can be used
                as any other PHP callable

$hello();


call_user_func($hello);
Anonymous Functions / Lambdas

                    You can also pass a lambda
               as an argument to a function or method

function foo(Closure $func)
{
  $func();
}

foo($hello);
Fonctions anonymes
$hello = function ($name) { echo 'Hello '.$name; };

$hello('Fabien');

call_user_func($hello, 'Fabien');

function foo(Closure $func, $name)
{
  $func($name);
}

foo($hello, 'Fabien');
DI Container

Managing objects
class Container
{
  protected $parameters = array();
  protected $objects = array();

    public function __set($key, $value)
    {
      $this->parameters[$key] = $value;
    }

    public function __get($key)                           Store a lambda
    {
      return $this->parameters[$key];                    able to create the
                                                         object on-demand
    }

    public function setService($key, Closure $service)
    {
      $this->objects[$key] = $service;
    }

    public function getService($key)            Ask the closure to create
    {
      return $this->objects[$key]($this);        th e object and pass the
}
    }                                                current Container
$container = new Container();
$container->session_name = 'SESSION_ID';               Description
$container->storage_class = 'SessionStorage';
$container->setService('user', function ($c)
{
  return new User($c->getService('storage'));
});
$container->setService('storage', function ($c)
{
  return new $c->storage_class($c->session_name);
});


                                              Creating the User
                                          is now as easy as before
$user = $container->getService('user');
class Container
{
  protected $values = array();               Simplify the code
    function __set($id, $value)
    {
      $this->values[$id] = $value;
    }

    function __get($id)
    {
      if (is_callable($this->values[$id]))
      {
        return $this->values[$id]($this);
      }
      else
      {
        return $this->values[$id];
      }
    }
}
$container = new Container();
                                            Unified interface
$container->session_name = 'SESSION_ID';
$container->storage_class = 'SessionStorage';
$container->user = function ($c)
{
   return new User($c->storage);
};
$container->storage = function ($c)
{
   return new $c->storage_class($c->session_name);
};




$user = $container->user;
DI Container

Scope
For some objects, like the user,
   the container must always
    return the same instance
spl_object_hash($container->user)



            !==
spl_object_hash($container->user)
$container->user = function ($c)
{
  static $user;

  if (is_null($user))
  {
    $user = new User($c->storage);
  }

  return $user;
};
spl_object_hash($container->user)



            ===
spl_object_hash($container->user)
$container->user = $container->asShared(function ($c)
{
  return new User($c->storage);
});
A closure is a lambda
that remembers the context
      of its creationā€¦
class Article
{
  public function __construct($title)
  {
    $this->title = $title;
  }

    public function getTitle()
    {
      return $this->title;
    }
}

$articles = array(
   new Article('Title 1'),
   new Article('Title 2'),
);
$mapper = function ($article)
{
   return $article->getTitle();
};

$titles = array_map($mapper, $articles);
$method = 'getTitle';

$mapper = function ($article) use($method)
{
   return $article->$method();
};

$method = 'getAuthor';

$titles = array_map($mapper, $articles);
$mapper = function ($method)
{
   return function ($article) use($method)
   {
      return $article->$method();
   };
};
$titles = array_map($mapper('getTitle'), $articles);


$authors = array_map($mapper('getAuthor'), $articles);
$container->user = $container->asShared(function ($c)
{
  return new User($c->storage);
});
function asShared(Closure $lambda)
{
  return function ($container) use ($lambda)
  {
    static $object;

      if (is_null($object))
      {
        $object = $lambda($container);
      }
      return $object;
    };
}
class Container
{
  protected $values = array();

    function __set($id, $value)
    {
      $this->values[$id] = $value;
    }

    function __get($id)
    {                                                            Error management
      if (!isset($this->values[$id]))
      {
        throw new InvalidArgumentException(sprintf('Value "%s" is not defined.', $id));
      }

        if (is_callable($this->values[$id]))
        {
          return $this->values[$id]($this);
        }
        else
        {
          return $this->values[$id];
        }
    }
}
class Container
{
  protected $values = array();

    function __set($id, $value)
    {
      $this->values[$id] = $value;
    }

    function __get($id)
    {
      if (!isset($this->values[$id]))
      {
        throw new InvalidArgumentException(sprintf('Value "%s" is not defined.', $id));
      }

        if (is_callable($this->values[$id]))
        {
          return $this->values[$id]($this);
        }
        else
        {
          return $this->values[$id];
        }
    }

    function asShared($callable)
    {


                                                                                          40 LOC for a fully-
      return function ($c) use ($callable)
      {
        static $object;

          if (is_null($object))
          {
            $object = $callable($c);
                                                                                          featured container
          }
          return $object;
        };
    }
}
Iā€™m NOT advocating
the usage of lambdas everywhere


   This presentation is about
    showing how they work
     on practical examples
A DI Container
does NOT manage
 ALL your objects
Good rule of thumb:
    It manages ā€œGlobalā€ objects

Objects with only one instance (!= Singletons)
LIKE
        a User, a Request,
a database Connection, a Logger, ā€¦
UNLIKE
Model objects (a Product, a blog Post, ā€¦)
Symfony Components
Dependency Injection
Rock-solid implementation of a DIC in PHP 5.3
At the core of the Symfony 2.0 framework

ā€¦ which is one of the fastest framework
Very ļ¬‚exible

Conļ¬guration in PHP, XML, YAML, or INI
$container = new Builder();
                                                                                         PHP
$container->register('output', 'FancyOutput');
$container->
  register('message', 'Message')->
  setArguments(array(new sfServiceReference('output'), array('with_newline' => true)))
;

$container->message->say('Hello World!');


services:
  output: { class: FancyOutput }
                                                                                         YAML
  message:
    class: Message
    arguments:
      - @output
      - { with_newline: true }

<container xmlns="http://symfony-project.org/schema/dic/services">
  <services>
    <service id="output" class="FancyOutput" />                                          XML
    <service id="message" class="Message">
      <argument type="service" id="output" />
      <argument type="collection">
        <argument key="with_newline">true</argument>
      </argument>
    </service>
  </services>
</container>
<container xmlns="http://symfony-project.org/schema/dic/services">
  <import resource="parameters.yml" />
  <import resource="parameters.ini" />
  <import resource="services.xml" />
</container>


imports:
 - { resource: parameters.yml }
 - { resource: parameters.ini }
 - { resource: services.xml }
Fast as hell
The container can be
  ā€œcompiledā€ down
  to plain PHP code
use SymfonyComponentsDependencyInjectionContainer;
use SymfonyComponentsDependencyInjectionReference;
use SymfonyComponentsDependencyInjectionParameter;

class ProjectServiceContainer extends Container
{
  protected $shared = array();

    protected function getOutputService()
    {
      if (isset($this->shared['output'])) return $this->shared['output'];

        $instance = new FancyOutput();

        return $this->shared['output'] = $instance;
    }

    protected function getMessageService()
    {
      if (isset($this->shared['message'])) return $this->shared['message'];

        $instance = new Message($this->getOutputService(), array('with_newline' => true));

        return $this->shared['message'] = $instance;
    }
}
Semantic conļ¬guration
Thanks to an extension mechanism
<container xmlns="http://www.symfony-project.org/schema/dic/services">

  <zend:logger
     priority="debug"
     path="%kernel.root_dir%/logs/%kernel.environment%.log" />

  <doctrine:dbal dbname="dbname" username="root" password="" />

  <swift:mailer transport="gmail">
    <swift:username>fabien.potencier</swift:username>
    <swift:password>xxxxxx</swift:password>
  </swift:mailer>

</container>
<container xmlns="http://www.symfony-project.org/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:swift="http://www.symfony-project.org/schema/dic/swiftmailer"
    xmlns:doctrine="http://www.symfony-project.org/schema/dic/doctrine"
    xmlns:zend="http://www.symfony-project.org/schema/dic/zend"
    xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-
project.org/schema/dic/services/services-1.0.xsd
                        http://www.symfony-project.org/schema/dic/doctrine http://www.symfony-
project.org/schema/dic/doctrine/doctrine-1.0.xsd
                        http://www.symfony-project.org/schema/dic/swiftmailer http://
www.symfony-project.org/schema/dic/swiftmailer/swiftmailer-1.0.xsd">

  <zend:logger priority="debug" path="%kernel.root_dir%/logs/%kernel.environment%.log" />

                                                         auto-completion
  <doctrine:dbal dbname="dbname" username="root" password="" />

  <swift:mailer transport="gmail">                        and validation
    <swift:username>fabien.potencier</swift:username>
    <swift:password>xxxxxx</swift:password>                  with XSD
  </swift:mailer>

</container>
zend.logger:
  level: debug
  path:   %kernel.root_dir%/logs/%kernel.environment%.log

doctrine.dbal:
  dbname: dbname
  username: root
  password: ~

swift.mailer:
  transport: gmail
  username: fabien.potencier
  password: xxxxxxx
Everything is converted by the extension
     to plain services and parameters
            no overhead
Loader::registerExtension(new SwiftMailerExtension());
Loader::registerExtension(new DoctrineExtension());
Loader::registerExtension(new ZendExtension());

$loader = new XmlFileLoader(__DIR__);
$config = $loader->load('services.xml');

$container = new Builder();
$container->merge($config);

$container->mailer->...

$dumper = new PhpDumper($container);
echo $dumper->dump();
More about Dependency Injection
http://fabien.potencier.org/article/17/on-php-5-3-lambda-functions-and-closures


http://components.symfony-project.org/dependency-injection/ (5.2)


http://github.com/fabpot/symfony/tree/master/src/Symfony/Components/DependencyInjection/(5.3)



http://github.com/fabpot/pimple


http://twittee.org/
Remember, most of the time,
 you donā€™t need a Container
to use Dependency Injection
You can start to use and beneļ¬t from
    Dependency Injection today
by implementing it
        in your projects

  by using externals libraries
      that already use DI
without the need of a container
Symfony
Zend Framework
 ezComponents
    Doctrine
  Swift Mailer
      ā€¦
Questions?

My slides will be available on
slideshare.com/fabpot
Sensio S.A.
    92-98, boulevard Victor Hugo
        92 115 Clichy Cedex
              FRANCE
       TĆ©l. : +33 1 40 99 80 80

               Contact
           Fabien Potencier
    fabien.potencier at sensio.com




  http://www.sensiolabs.com/
http://www.symfony-project.org/
 http://fabien.potencier.org/

More Related Content

What's hot

The State of Lithium
The State of LithiumThe State of Lithium
The State of LithiumNate Abele
Ā 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionNate Abele
Ā 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
Ā 
PHP Data Objects
PHP Data ObjectsPHP Data Objects
PHP Data ObjectsWez Furlong
Ā 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkG Woo
Ā 
Drupal 8 database api
Drupal 8 database apiDrupal 8 database api
Drupal 8 database apiViswanath Polaki
Ā 
ē©¶ę„µć®ć‚³ćƒ³ćƒˆćƒ­ćƒ¼ćƒ©ć‚’ē›®ęŒ‡ć™
ē©¶ę„µć®ć‚³ćƒ³ćƒˆćƒ­ćƒ¼ćƒ©ć‚’ē›®ęŒ‡ć™ē©¶ę„µć®ć‚³ćƒ³ćƒˆćƒ­ćƒ¼ćƒ©ć‚’ē›®ęŒ‡ć™
ē©¶ę„µć®ć‚³ćƒ³ćƒˆćƒ­ćƒ¼ćƒ©ć‚’ē›®ęŒ‡ć™Yasuo Harada
Ā 
Dependency Injection
Dependency InjectionDependency Injection
Dependency InjectionRifat Nabi
Ā 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design PatternsHugo Hamon
Ā 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
Ā 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
Ā 
Drupal Entities - Emerging Patterns of Usage
Drupal Entities - Emerging Patterns of UsageDrupal Entities - Emerging Patterns of Usage
Drupal Entities - Emerging Patterns of UsageRonald Ashri
Ā 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Fabien Potencier
Ā 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of LithiumNate Abele
Ā 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConRafael Dohms
Ā 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleHugo Hamon
Ā 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsRoss Tuck
Ā 
Build your own entity with Drupal
Build your own entity with DrupalBuild your own entity with Drupal
Build your own entity with DrupalMarco Vito Moscaritolo
Ā 

What's hot (20)

The State of Lithium
The State of LithiumThe State of Lithium
The State of Lithium
Ā 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Ā 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
Ā 
PHP Data Objects
PHP Data ObjectsPHP Data Objects
PHP Data Objects
Ā 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
Ā 
Drupal 8 database api
Drupal 8 database apiDrupal 8 database api
Drupal 8 database api
Ā 
ē©¶ę„µć®ć‚³ćƒ³ćƒˆćƒ­ćƒ¼ćƒ©ć‚’ē›®ęŒ‡ć™
ē©¶ę„µć®ć‚³ćƒ³ćƒˆćƒ­ćƒ¼ćƒ©ć‚’ē›®ęŒ‡ć™ē©¶ę„µć®ć‚³ćƒ³ćƒˆćƒ­ćƒ¼ćƒ©ć‚’ē›®ęŒ‡ć™
ē©¶ę„µć®ć‚³ćƒ³ćƒˆćƒ­ćƒ¼ćƒ©ć‚’ē›®ęŒ‡ć™
Ā 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
Ā 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
Ā 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
Ā 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
Ā 
Drupal Entities - Emerging Patterns of Usage
Drupal Entities - Emerging Patterns of UsageDrupal Entities - Emerging Patterns of Usage
Drupal Entities - Emerging Patterns of Usage
Ā 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
Ā 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
Ā 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
Ā 
Drupal7 dbtng
Drupal7  dbtngDrupal7  dbtng
Drupal7 dbtng
Ā 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnCon
Ā 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
Ā 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and Hobgoblins
Ā 
Build your own entity with Drupal
Build your own entity with DrupalBuild your own entity with Drupal
Build your own entity with Drupal
Ā 

Viewers also liked

Advanced Google Analytics: Top 10 Things Your Association Should be Measuring...
Advanced Google Analytics: Top 10 Things Your Association Should be Measuring...Advanced Google Analytics: Top 10 Things Your Association Should be Measuring...
Advanced Google Analytics: Top 10 Things Your Association Should be Measuring...WebLink International
Ā 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 WorldFabien Potencier
Ā 
Caching on the Edge with Symfony2
Caching on the Edge with Symfony2Caching on the Edge with Symfony2
Caching on the Edge with Symfony2Fabien Potencier
Ā 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2Fabien Potencier
Ā 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Fabien Potencier
Ā 
You Shall Not Pass - Security in Symfony
You Shall Not Pass - Security in SymfonyYou Shall Not Pass - Security in Symfony
You Shall Not Pass - Security in SymfonyThe Software House
Ā 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Fabien Potencier
Ā 

Viewers also liked (12)

Advanced Google Analytics: Top 10 Things Your Association Should be Measuring...
Advanced Google Analytics: Top 10 Things Your Association Should be Measuring...Advanced Google Analytics: Top 10 Things Your Association Should be Measuring...
Advanced Google Analytics: Top 10 Things Your Association Should be Measuring...
Ā 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
Ā 
Caching on the Edge with Symfony2
Caching on the Edge with Symfony2Caching on the Edge with Symfony2
Caching on the Edge with Symfony2
Ā 
PHP 5.3 in practice
PHP 5.3 in practicePHP 5.3 in practice
PHP 5.3 in practice
Ā 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
Ā 
Look beyond PHP
Look beyond PHPLook beyond PHP
Look beyond PHP
Ā 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2
Ā 
Symfony Components
Symfony ComponentsSymfony Components
Symfony Components
Ā 
You Shall Not Pass - Security in Symfony
You Shall Not Pass - Security in SymfonyYou Shall Not Pass - Security in Symfony
You Shall Not Pass - Security in Symfony
Ā 
Testing and symfony2
Testing and symfony2Testing and symfony2
Testing and symfony2
Ā 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3
Ā 
Varnish
VarnishVarnish
Varnish
Ā 

Similar to Dependency Injection - ConFoo 2010

Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Fabien Potencier
Ā 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8Alexei Gorobets
Ā 
Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Fabien Potencier
Ā 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Jeff Carouth
Ā 
Caching and Scaling WordPress using Fragment Caching
Caching and Scaling WordPress using Fragment CachingCaching and Scaling WordPress using Fragment Caching
Caching and Scaling WordPress using Fragment CachingErick Hitter
Ā 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
Ā 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf Conference
Ā 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC HydraKacper Gunia
Ā 
MUC - Moodle Universal Cache
MUC - Moodle Universal CacheMUC - Moodle Universal Cache
MUC - Moodle Universal CacheTim Hunt
Ā 
PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodeSWIFTotter Solutions
Ā 
Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperJonathan Wage
Ā 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologyDaniel Knell
Ā 
Lecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptxLecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptxDavidLazar17
Ā 
Drupal 8 Services And Dependency Injection
Drupal 8 Services And Dependency InjectionDrupal 8 Services And Dependency Injection
Drupal 8 Services And Dependency InjectionPhilip Norton
Ā 
laravel tricks in 50minutes
laravel tricks in 50minuteslaravel tricks in 50minutes
laravel tricks in 50minutesBarang CK
Ā 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 MinutesAzim Kurt
Ā 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Developmentjsmith92
Ā 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEnterprise PHP Center
Ā 

Similar to Dependency Injection - ConFoo 2010 (20)

Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3
Ā 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
Ā 
Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)
Ā 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
Ā 
Caching and Scaling WordPress using Fragment Caching
Caching and Scaling WordPress using Fragment CachingCaching and Scaling WordPress using Fragment Caching
Caching and Scaling WordPress using Fragment Caching
Ā 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
Ā 
PHP pod mikroskopom
PHP pod mikroskopomPHP pod mikroskopom
PHP pod mikroskopom
Ā 
Oops in php
Oops in phpOops in php
Oops in php
Ā 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
Ā 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
Ā 
MUC - Moodle Universal Cache
MUC - Moodle Universal CacheMUC - Moodle Universal Cache
MUC - Moodle Universal Cache
Ā 
PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better Code
Ā 
Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document Mapper
Ā 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
Ā 
Lecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptxLecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptx
Ā 
Drupal 8 Services And Dependency Injection
Drupal 8 Services And Dependency InjectionDrupal 8 Services And Dependency Injection
Drupal 8 Services And Dependency Injection
Ā 
laravel tricks in 50minutes
laravel tricks in 50minuteslaravel tricks in 50minutes
laravel tricks in 50minutes
Ā 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
Ā 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
Ā 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
Ā 

More from Fabien Potencier

The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010Fabien Potencier
Ā 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010Fabien Potencier
Ā 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Fabien Potencier
Ā 
Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010Fabien Potencier
Ā 
Dependency Injection
Dependency InjectionDependency Injection
Dependency InjectionFabien Potencier
Ā 
Symfony Components 2.0 on PHP 5.3
Symfony Components 2.0 on PHP 5.3Symfony Components 2.0 on PHP 5.3
Symfony Components 2.0 on PHP 5.3Fabien Potencier
Ā 
Playing With PHP 5.3
Playing With PHP 5.3Playing With PHP 5.3
Playing With PHP 5.3Fabien Potencier
Ā 
Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3Fabien Potencier
Ā 
Symfony2 San Francisco Meetup 2009
Symfony2 San Francisco Meetup 2009Symfony2 San Francisco Meetup 2009
Symfony2 San Francisco Meetup 2009Fabien Potencier
Ā 
Symfony And Zend Framework Together 2009
Symfony And Zend Framework Together 2009Symfony And Zend Framework Together 2009
Symfony And Zend Framework Together 2009Fabien Potencier
Ā 
Twig, the flexible, fast, and secure template language for PHP
Twig, the flexible, fast, and secure template language for PHPTwig, the flexible, fast, and secure template language for PHP
Twig, the flexible, fast, and secure template language for PHPFabien Potencier
Ā 
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)Fabien Potencier
Ā 
The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)Fabien Potencier
Ā 

More from Fabien Potencier (15)

Caching on the Edge
Caching on the EdgeCaching on the Edge
Caching on the Edge
Ā 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010
Ā 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010
Ā 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
Ā 
Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010
Ā 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
Ā 
Symfony2 revealed
Symfony2 revealedSymfony2 revealed
Symfony2 revealed
Ā 
Symfony Components 2.0 on PHP 5.3
Symfony Components 2.0 on PHP 5.3Symfony Components 2.0 on PHP 5.3
Symfony Components 2.0 on PHP 5.3
Ā 
Playing With PHP 5.3
Playing With PHP 5.3Playing With PHP 5.3
Playing With PHP 5.3
Ā 
Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3
Ā 
Symfony2 San Francisco Meetup 2009
Symfony2 San Francisco Meetup 2009Symfony2 San Francisco Meetup 2009
Symfony2 San Francisco Meetup 2009
Ā 
Symfony And Zend Framework Together 2009
Symfony And Zend Framework Together 2009Symfony And Zend Framework Together 2009
Symfony And Zend Framework Together 2009
Ā 
Twig, the flexible, fast, and secure template language for PHP
Twig, the flexible, fast, and secure template language for PHPTwig, the flexible, fast, and secure template language for PHP
Twig, the flexible, fast, and secure template language for PHP
Ā 
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)
Ā 
The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)
Ā 

Recently uploaded

Grateful 7 speech thanking everyone that has helped.pdf
Grateful 7 speech thanking everyone that has helped.pdfGrateful 7 speech thanking everyone that has helped.pdf
Grateful 7 speech thanking everyone that has helped.pdfPaul Menig
Ā 
M.C Lodges -- Guest House in Jhang.
M.C Lodges --  Guest House in Jhang.M.C Lodges --  Guest House in Jhang.
M.C Lodges -- Guest House in Jhang.Aaiza Hassan
Ā 
The Coffee Bean & Tea Leaf(CBTL), Business strategy case study
The Coffee Bean & Tea Leaf(CBTL), Business strategy case studyThe Coffee Bean & Tea Leaf(CBTL), Business strategy case study
The Coffee Bean & Tea Leaf(CBTL), Business strategy case studyEthan lee
Ā 
Lucknow šŸ’‹ Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...
Lucknow šŸ’‹ Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...Lucknow šŸ’‹ Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...
Lucknow šŸ’‹ Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...anilsa9823
Ā 
KYC-Verified Accounts: Helping Companies Handle Challenging Regulatory Enviro...
KYC-Verified Accounts: Helping Companies Handle Challenging Regulatory Enviro...KYC-Verified Accounts: Helping Companies Handle Challenging Regulatory Enviro...
KYC-Verified Accounts: Helping Companies Handle Challenging Regulatory Enviro...Any kyc Account
Ā 
A DAY IN THE LIFE OF A SALESMAN / WOMAN
A DAY IN THE LIFE OF A  SALESMAN / WOMANA DAY IN THE LIFE OF A  SALESMAN / WOMAN
A DAY IN THE LIFE OF A SALESMAN / WOMANIlamathiKannappan
Ā 
7.pdf This presentation captures many uses and the significance of the number...
7.pdf This presentation captures many uses and the significance of the number...7.pdf This presentation captures many uses and the significance of the number...
7.pdf This presentation captures many uses and the significance of the number...Paul Menig
Ā 
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...Dave Litwiller
Ā 
Call Girls In DLf Gurgaon āž„99902@11544 ( Best price)100% Genuine Escort In 24...
Call Girls In DLf Gurgaon āž„99902@11544 ( Best price)100% Genuine Escort In 24...Call Girls In DLf Gurgaon āž„99902@11544 ( Best price)100% Genuine Escort In 24...
Call Girls In DLf Gurgaon āž„99902@11544 ( Best price)100% Genuine Escort In 24...lizamodels9
Ā 
MONA 98765-12871 CALL GIRLS IN LUDHIANA LUDHIANA CALL GIRL
MONA 98765-12871 CALL GIRLS IN LUDHIANA LUDHIANA CALL GIRLMONA 98765-12871 CALL GIRLS IN LUDHIANA LUDHIANA CALL GIRL
MONA 98765-12871 CALL GIRLS IN LUDHIANA LUDHIANA CALL GIRLSeo
Ā 
Russian Call Girls In Gurgaon ā¤ļø8448577510 āŠ¹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ā¤ļø8448577510 āŠ¹Best Escorts Service In 24/7 Delh...Russian Call Girls In Gurgaon ā¤ļø8448577510 āŠ¹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ā¤ļø8448577510 āŠ¹Best Escorts Service In 24/7 Delh...lizamodels9
Ā 
B.COM Unit ā€“ 4 ( CORPORATE SOCIAL RESPONSIBILITY ( CSR ).pptx
B.COM Unit ā€“ 4 ( CORPORATE SOCIAL RESPONSIBILITY ( CSR ).pptxB.COM Unit ā€“ 4 ( CORPORATE SOCIAL RESPONSIBILITY ( CSR ).pptx
B.COM Unit ā€“ 4 ( CORPORATE SOCIAL RESPONSIBILITY ( CSR ).pptxpriyanshujha201
Ā 
Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023Neil Kimberley
Ā 
HONOR Veterans Event Keynote by Michael Hawkins
HONOR Veterans Event Keynote by Michael HawkinsHONOR Veterans Event Keynote by Michael Hawkins
HONOR Veterans Event Keynote by Michael HawkinsMichael W. Hawkins
Ā 
How to Get Started in Social Media for Art League City
How to Get Started in Social Media for Art League CityHow to Get Started in Social Media for Art League City
How to Get Started in Social Media for Art League CityEric T. Tung
Ā 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756dollysharma2066
Ā 
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779Best VIP Call Girls Noida Sector 40 Call Me: 8448380779
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779Delhi Call girls
Ā 
Regression analysis: Simple Linear Regression Multiple Linear Regression
Regression analysis:  Simple Linear Regression Multiple Linear RegressionRegression analysis:  Simple Linear Regression Multiple Linear Regression
Regression analysis: Simple Linear Regression Multiple Linear RegressionRavindra Nath Shukla
Ā 
VIP Call Girls In Saharaganj ( Lucknow ) šŸ” 8923113531 šŸ” Cash Payment (COD) šŸ‘’
VIP Call Girls In Saharaganj ( Lucknow  ) šŸ” 8923113531 šŸ”  Cash Payment (COD) šŸ‘’VIP Call Girls In Saharaganj ( Lucknow  ) šŸ” 8923113531 šŸ”  Cash Payment (COD) šŸ‘’
VIP Call Girls In Saharaganj ( Lucknow ) šŸ” 8923113531 šŸ” Cash Payment (COD) šŸ‘’anilsa9823
Ā 
Organizational Transformation Lead with Culture
Organizational Transformation Lead with CultureOrganizational Transformation Lead with Culture
Organizational Transformation Lead with CultureSeta Wicaksana
Ā 

Recently uploaded (20)

Grateful 7 speech thanking everyone that has helped.pdf
Grateful 7 speech thanking everyone that has helped.pdfGrateful 7 speech thanking everyone that has helped.pdf
Grateful 7 speech thanking everyone that has helped.pdf
Ā 
M.C Lodges -- Guest House in Jhang.
M.C Lodges --  Guest House in Jhang.M.C Lodges --  Guest House in Jhang.
M.C Lodges -- Guest House in Jhang.
Ā 
The Coffee Bean & Tea Leaf(CBTL), Business strategy case study
The Coffee Bean & Tea Leaf(CBTL), Business strategy case studyThe Coffee Bean & Tea Leaf(CBTL), Business strategy case study
The Coffee Bean & Tea Leaf(CBTL), Business strategy case study
Ā 
Lucknow šŸ’‹ Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...
Lucknow šŸ’‹ Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...Lucknow šŸ’‹ Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...
Lucknow šŸ’‹ Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...
Ā 
KYC-Verified Accounts: Helping Companies Handle Challenging Regulatory Enviro...
KYC-Verified Accounts: Helping Companies Handle Challenging Regulatory Enviro...KYC-Verified Accounts: Helping Companies Handle Challenging Regulatory Enviro...
KYC-Verified Accounts: Helping Companies Handle Challenging Regulatory Enviro...
Ā 
A DAY IN THE LIFE OF A SALESMAN / WOMAN
A DAY IN THE LIFE OF A  SALESMAN / WOMANA DAY IN THE LIFE OF A  SALESMAN / WOMAN
A DAY IN THE LIFE OF A SALESMAN / WOMAN
Ā 
7.pdf This presentation captures many uses and the significance of the number...
7.pdf This presentation captures many uses and the significance of the number...7.pdf This presentation captures many uses and the significance of the number...
7.pdf This presentation captures many uses and the significance of the number...
Ā 
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Ā 
Call Girls In DLf Gurgaon āž„99902@11544 ( Best price)100% Genuine Escort In 24...
Call Girls In DLf Gurgaon āž„99902@11544 ( Best price)100% Genuine Escort In 24...Call Girls In DLf Gurgaon āž„99902@11544 ( Best price)100% Genuine Escort In 24...
Call Girls In DLf Gurgaon āž„99902@11544 ( Best price)100% Genuine Escort In 24...
Ā 
MONA 98765-12871 CALL GIRLS IN LUDHIANA LUDHIANA CALL GIRL
MONA 98765-12871 CALL GIRLS IN LUDHIANA LUDHIANA CALL GIRLMONA 98765-12871 CALL GIRLS IN LUDHIANA LUDHIANA CALL GIRL
MONA 98765-12871 CALL GIRLS IN LUDHIANA LUDHIANA CALL GIRL
Ā 
Russian Call Girls In Gurgaon ā¤ļø8448577510 āŠ¹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ā¤ļø8448577510 āŠ¹Best Escorts Service In 24/7 Delh...Russian Call Girls In Gurgaon ā¤ļø8448577510 āŠ¹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ā¤ļø8448577510 āŠ¹Best Escorts Service In 24/7 Delh...
Ā 
B.COM Unit ā€“ 4 ( CORPORATE SOCIAL RESPONSIBILITY ( CSR ).pptx
B.COM Unit ā€“ 4 ( CORPORATE SOCIAL RESPONSIBILITY ( CSR ).pptxB.COM Unit ā€“ 4 ( CORPORATE SOCIAL RESPONSIBILITY ( CSR ).pptx
B.COM Unit ā€“ 4 ( CORPORATE SOCIAL RESPONSIBILITY ( CSR ).pptx
Ā 
Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023
Ā 
HONOR Veterans Event Keynote by Michael Hawkins
HONOR Veterans Event Keynote by Michael HawkinsHONOR Veterans Event Keynote by Michael Hawkins
HONOR Veterans Event Keynote by Michael Hawkins
Ā 
How to Get Started in Social Media for Art League City
How to Get Started in Social Media for Art League CityHow to Get Started in Social Media for Art League City
How to Get Started in Social Media for Art League City
Ā 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
Ā 
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779Best VIP Call Girls Noida Sector 40 Call Me: 8448380779
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779
Ā 
Regression analysis: Simple Linear Regression Multiple Linear Regression
Regression analysis:  Simple Linear Regression Multiple Linear RegressionRegression analysis:  Simple Linear Regression Multiple Linear Regression
Regression analysis: Simple Linear Regression Multiple Linear Regression
Ā 
VIP Call Girls In Saharaganj ( Lucknow ) šŸ” 8923113531 šŸ” Cash Payment (COD) šŸ‘’
VIP Call Girls In Saharaganj ( Lucknow  ) šŸ” 8923113531 šŸ”  Cash Payment (COD) šŸ‘’VIP Call Girls In Saharaganj ( Lucknow  ) šŸ” 8923113531 šŸ”  Cash Payment (COD) šŸ‘’
VIP Call Girls In Saharaganj ( Lucknow ) šŸ” 8923113531 šŸ” Cash Payment (COD) šŸ‘’
Ā 
Organizational Transformation Lead with Culture
Organizational Transformation Lead with CultureOrganizational Transformation Lead with Culture
Organizational Transformation Lead with Culture
Ā 

Dependency Injection - ConFoo 2010

  • 1. Dependency Injection with PHP 5.3 Fabien Potencier
  • 2. Fabien Potencier Serial entrepreneur Developer by passion Founder of Sensio Creator and lead developer of Symfony On Twitter @fabpot On github http://www.github.com/fabpot Blog http://fabien.potencier.org/
  • 3. Dependency Injection A real world Ā«Ā webĀ Ā» example
  • 4. In most web applications, you need to manage the user preferences ā€“ā€Æ The user language ā€“ā€Æ Whether the user is authenticated or not ā€“ā€Æ The user credentials ā€“ā€Æ ā€¦
  • 5. This can be done with a User object ā€“ā€Æ setLanguage(), getLanguage() ā€“ā€Æ setAuthenticated(), isAuthenticated() ā€“ā€Æ addCredential(), hasCredential() ā€“ā€Æ ...
  • 6. The User information need to be persisted between HTTP requests We use the PHP session for the Storage
  • 7. class SessionStorage { function __construct($cookieName = 'PHP_SESS_ID') { session_name($cookieName); session_start(); } function set($key, $value) { $_SESSION[$key] = $value; } // ... }
  • 8. class User { protected $storage; function __construct() Very hard to { customize $this->storage = new SessionStorage(); } function setLanguage($language) { $this->storage->set('language', $language); } // ... } Very easy to use $user = new User();
  • 9. class User { protected $storage; Very easy to customize function __construct($storage) { $this->storage = $storage; } } $storage = new SessionStorage(); $user = new User($storage); Slightly more difficult to use
  • 11. Letā€™s understand why the ļ¬rst example is not a good idea
  • 12. I want to change the session cookie name
  • 13. class User { protected $storage; function __construct() Hardcode it in the { User class $this->storage = new SessionStorage('SESSION_ID'); } function setLanguage($language) { $this->storage->set('language', $language); } // ... } $user = new User();
  • 14. class User { protected $storage; function __construct() { $this->storage = new SessionStorage(STORAGE_SESSION_NAME); } } Add a global configuration? define('STORAGE_SESSION_NAME', 'SESSION_ID'); $user = new User();
  • 15. class User { protected $storage; function __construct($sessionName) { $this->storage = new SessionStorage($sessionName); } } $user = new User('SESSION_ID'); Configure via User?
  • 16. class User { protected $storage; function __construct($storageOptions) { $this->storage = new SessionStorage($storageOptions ['session_name']); $user = new User( array('session_name' => 'SESSION_ID') ); Configure with an array?
  • 17. I want to change the session storage implementation Filesystem MySQL Memcached ā€¦
  • 18. class User { protected $storage; function __construct() Use a global { registry object? $this->storage = Registry::get('session_storage'); } } $storage = new SessionStorage(); Registry::set('session_storage', $storage); $user = new User();
  • 19. Now, the User depends on the Registry
  • 20. Instead of harcoding the Storage dependency inside the User class constructor Inject the Storage dependency in the User object
  • 21. class User { protected $storage; function __construct($storage) { $this->storage = $storage; } } $storage = new SessionStorage('SESSION_ID'); $user = new User($storage);
  • 22. What are the advantages?
  • 24. class User { protected $storage; function __construct($storage) { $this->storage = $storage; } } Use a different Storage engine $storage = new MySQLSessionStorage('SESSION_ID'); $user = new User($storage);
  • 26. class User { protected $storage; function __construct($storage) { $this->storage = $storage; } } Configuration is natural $storage = new MySQLSessionStorage('SESSION_ID'); $user = new User($storage);
  • 27. Wrap third-party classes (Interface / Adapter)
  • 28. class User { protected $storage; Add an interface function __construct(SessionStorageInterface $storage) { $this->storage = $storage; } } interface SessionStorageInterface { function get($key); function set($key, $value); }
  • 29. Mock the Storage object (for testing)
  • 30. class User { protected $storage; function __construct(SessionStorageInterface $storage) { $this->storage = $storage; } } Mock the Session class SessionStorageForTests implements SessionStorageInterface { protected $data = array(); static function set($key, $value) { self::$data[$key] = $value; } }
  • 31. Use diļ¬€erent Storage strategies Conļ¬guration becomes natural Wrap third-party classes (Interface / Adapter) Mock the Storage object (for testing) Easy without changing the User class
  • 32. Ā«Ā Dependency Injection is where components are given their dependencies through their constructors, methods, or directly into ļ¬elds.Ā Ā» http://www.picocontainer.org/injection.html
  • 33. $storage = new SessionStorage(); // constructor injection $user = new User($storage); // setter injection $user = new User(); $user->setStorage($storage); // property injection $user = new User(); $user->storage = $storage;
  • 34. A slightly more complex web example
  • 35. $request = new Request(); $response = new Response(); $storage = new FileSessionStorage('SESSION_ID'); $user = new User($storage); $cache = new FileCache( array('dir' => dirname(__FILE__).'/cache') ); $routing = new Routing($cache);
  • 36. class Application { function __construct() { $this->request = new WebRequest(); $this->response = new WebResponse(); $storage = new FileSessionStorage('SESSION_ID'); $this->user = new User($storage); $cache = new FileCache( array('dir' => dirname(__FILE__).'/cache') ); $this->routing = new Routing($cache); } } $application = new Application();
  • 38. class Application { function __construct() { $this->request = new WebRequest(); $this->response = new WebResponse(); $storage = new FileSessionStorage('SESSION_ID'); $this->user = new User($storage); $cache = new FileCache( array('dir' => dirname(__FILE__).'/cache') ); $this->routing = new Routing($cache); } } $application = new Application();
  • 39. We need a Container Describes objects and their dependencies Instantiates and conļ¬gures objects on-demand
  • 40. A container SHOULD be able to manage ANY PHP object (POPO) The objects MUST not know that they are managed by a container
  • 41. ā€¢ā€Æ Parameters ā€“ā€Æ The SessionStorageInterface implementation we want to use (the class name) ā€“ā€Æ The session name ā€¢ā€Æ Objects ā€“ā€Æ SessionStorage ā€“ā€Æ User ā€¢ā€Æ Dependencies ā€“ā€Æ User depends on a SessionStorageInterface implementation
  • 42. Letā€™s build a simple container with PHP 5.3
  • 44. class Container { protected $parameters = array(); public function setParameter($key, $value) { $this->parameters[$key] = $value; } public function getParameter($key) { return $this->parameters[$key]; } }
  • 45. Decoupling $container = new Container(); Customization $container->setParameter('session_name', 'SESSION_ID'); $container->setParameter('storage_class', 'SessionStorage'); $class = $container->getParameter('storage_class'); $sessionStorage = new $class($container->getParameter('session_name')); $user = new User($sessionStorage); Objects creation
  • 46. class Container Using PHP { magic methods protected $parameters = array(); public function __set($key, $value) { $this->parameters[$key] = $value; } public function __get($key) { return $this->parameters[$key]; } }
  • 47. Interface is cleaner $container = new Container(); $container->session_name = 'SESSION_ID'; $container->storage_class = 'SessionStorage'; $sessionStorage = new $container->storage_class($container->session_name); $user = new User($sessionStorage);
  • 49. We need a way to describe how to create objects, without actually instantiating anything! Anonymous functions to the rescue!
  • 50. Anonymous Functions / Lambdas A lambda is a function deļ¬ned on the ļ¬‚y with no name function () { echo 'Hello world!'; };
  • 51. Anonymous Functions / Lambdas A lambda can be stored in a variable $hello = function () { echo 'Hello world!'; };
  • 52. Anonymous Functions / Lambdas And then it can be used as any other PHP callable $hello(); call_user_func($hello);
  • 53. Anonymous Functions / Lambdas You can also pass a lambda as an argument to a function or method function foo(Closure $func) { $func(); } foo($hello);
  • 54. Fonctions anonymes $hello = function ($name) { echo 'Hello '.$name; }; $hello('Fabien'); call_user_func($hello, 'Fabien'); function foo(Closure $func, $name) { $func($name); } foo($hello, 'Fabien');
  • 56. class Container { protected $parameters = array(); protected $objects = array(); public function __set($key, $value) { $this->parameters[$key] = $value; } public function __get($key) Store a lambda { return $this->parameters[$key]; able to create the object on-demand } public function setService($key, Closure $service) { $this->objects[$key] = $service; } public function getService($key) Ask the closure to create { return $this->objects[$key]($this); th e object and pass the } } current Container
  • 57. $container = new Container(); $container->session_name = 'SESSION_ID'; Description $container->storage_class = 'SessionStorage'; $container->setService('user', function ($c) { return new User($c->getService('storage')); }); $container->setService('storage', function ($c) { return new $c->storage_class($c->session_name); }); Creating the User is now as easy as before $user = $container->getService('user');
  • 58. class Container { protected $values = array(); Simplify the code function __set($id, $value) { $this->values[$id] = $value; } function __get($id) { if (is_callable($this->values[$id])) { return $this->values[$id]($this); } else { return $this->values[$id]; } } }
  • 59. $container = new Container(); Unified interface $container->session_name = 'SESSION_ID'; $container->storage_class = 'SessionStorage'; $container->user = function ($c) { return new User($c->storage); }; $container->storage = function ($c) { return new $c->storage_class($c->session_name); }; $user = $container->user;
  • 61. For some objects, like the user, the container must always return the same instance
  • 62. spl_object_hash($container->user) !== spl_object_hash($container->user)
  • 63. $container->user = function ($c) { static $user; if (is_null($user)) { $user = new User($c->storage); } return $user; };
  • 64. spl_object_hash($container->user) === spl_object_hash($container->user)
  • 65. $container->user = $container->asShared(function ($c) { return new User($c->storage); });
  • 66. A closure is a lambda that remembers the context of its creationā€¦
  • 67. class Article { public function __construct($title) { $this->title = $title; } public function getTitle() { return $this->title; } } $articles = array( new Article('Title 1'), new Article('Title 2'), );
  • 68. $mapper = function ($article) { return $article->getTitle(); }; $titles = array_map($mapper, $articles);
  • 69. $method = 'getTitle'; $mapper = function ($article) use($method) { return $article->$method(); }; $method = 'getAuthor'; $titles = array_map($mapper, $articles);
  • 70. $mapper = function ($method) { return function ($article) use($method) { return $article->$method(); }; };
  • 71. $titles = array_map($mapper('getTitle'), $articles); $authors = array_map($mapper('getAuthor'), $articles);
  • 72. $container->user = $container->asShared(function ($c) { return new User($c->storage); });
  • 73. function asShared(Closure $lambda) { return function ($container) use ($lambda) { static $object; if (is_null($object)) { $object = $lambda($container); } return $object; }; }
  • 74. class Container { protected $values = array(); function __set($id, $value) { $this->values[$id] = $value; } function __get($id) { Error management if (!isset($this->values[$id])) { throw new InvalidArgumentException(sprintf('Value "%s" is not defined.', $id)); } if (is_callable($this->values[$id])) { return $this->values[$id]($this); } else { return $this->values[$id]; } } }
  • 75. class Container { protected $values = array(); function __set($id, $value) { $this->values[$id] = $value; } function __get($id) { if (!isset($this->values[$id])) { throw new InvalidArgumentException(sprintf('Value "%s" is not defined.', $id)); } if (is_callable($this->values[$id])) { return $this->values[$id]($this); } else { return $this->values[$id]; } } function asShared($callable) { 40 LOC for a fully- return function ($c) use ($callable) { static $object; if (is_null($object)) { $object = $callable($c); featured container } return $object; }; } }
  • 76. Iā€™m NOT advocating the usage of lambdas everywhere This presentation is about showing how they work on practical examples
  • 77. A DI Container does NOT manage ALL your objects
  • 78. Good rule of thumb: It manages ā€œGlobalā€ objects Objects with only one instance (!= Singletons)
  • 79. LIKE a User, a Request, a database Connection, a Logger, ā€¦
  • 80. UNLIKE Model objects (a Product, a blog Post, ā€¦)
  • 82. Rock-solid implementation of a DIC in PHP 5.3
  • 83. At the core of the Symfony 2.0 framework ā€¦ which is one of the fastest framework
  • 84. Very ļ¬‚exible Conļ¬guration in PHP, XML, YAML, or INI
  • 85. $container = new Builder(); PHP $container->register('output', 'FancyOutput'); $container-> register('message', 'Message')-> setArguments(array(new sfServiceReference('output'), array('with_newline' => true))) ; $container->message->say('Hello World!'); services: output: { class: FancyOutput } YAML message: class: Message arguments: - @output - { with_newline: true } <container xmlns="http://symfony-project.org/schema/dic/services"> <services> <service id="output" class="FancyOutput" /> XML <service id="message" class="Message"> <argument type="service" id="output" /> <argument type="collection"> <argument key="with_newline">true</argument> </argument> </service> </services> </container>
  • 86. <container xmlns="http://symfony-project.org/schema/dic/services"> <import resource="parameters.yml" /> <import resource="parameters.ini" /> <import resource="services.xml" /> </container> imports: - { resource: parameters.yml } - { resource: parameters.ini } - { resource: services.xml }
  • 87. Fast as hell The container can be ā€œcompiledā€ down to plain PHP code
  • 88. use SymfonyComponentsDependencyInjectionContainer; use SymfonyComponentsDependencyInjectionReference; use SymfonyComponentsDependencyInjectionParameter; class ProjectServiceContainer extends Container { protected $shared = array(); protected function getOutputService() { if (isset($this->shared['output'])) return $this->shared['output']; $instance = new FancyOutput(); return $this->shared['output'] = $instance; } protected function getMessageService() { if (isset($this->shared['message'])) return $this->shared['message']; $instance = new Message($this->getOutputService(), array('with_newline' => true)); return $this->shared['message'] = $instance; } }
  • 89. Semantic conļ¬guration Thanks to an extension mechanism
  • 90. <container xmlns="http://www.symfony-project.org/schema/dic/services"> <zend:logger priority="debug" path="%kernel.root_dir%/logs/%kernel.environment%.log" /> <doctrine:dbal dbname="dbname" username="root" password="" /> <swift:mailer transport="gmail"> <swift:username>fabien.potencier</swift:username> <swift:password>xxxxxx</swift:password> </swift:mailer> </container>
  • 91. <container xmlns="http://www.symfony-project.org/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:swift="http://www.symfony-project.org/schema/dic/swiftmailer" xmlns:doctrine="http://www.symfony-project.org/schema/dic/doctrine" xmlns:zend="http://www.symfony-project.org/schema/dic/zend" xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony- project.org/schema/dic/services/services-1.0.xsd http://www.symfony-project.org/schema/dic/doctrine http://www.symfony- project.org/schema/dic/doctrine/doctrine-1.0.xsd http://www.symfony-project.org/schema/dic/swiftmailer http:// www.symfony-project.org/schema/dic/swiftmailer/swiftmailer-1.0.xsd"> <zend:logger priority="debug" path="%kernel.root_dir%/logs/%kernel.environment%.log" /> auto-completion <doctrine:dbal dbname="dbname" username="root" password="" /> <swift:mailer transport="gmail"> and validation <swift:username>fabien.potencier</swift:username> <swift:password>xxxxxx</swift:password> with XSD </swift:mailer> </container>
  • 92. zend.logger: level: debug path: %kernel.root_dir%/logs/%kernel.environment%.log doctrine.dbal: dbname: dbname username: root password: ~ swift.mailer: transport: gmail username: fabien.potencier password: xxxxxxx
  • 93. Everything is converted by the extension to plain services and parameters no overhead
  • 94. Loader::registerExtension(new SwiftMailerExtension()); Loader::registerExtension(new DoctrineExtension()); Loader::registerExtension(new ZendExtension()); $loader = new XmlFileLoader(__DIR__); $config = $loader->load('services.xml'); $container = new Builder(); $container->merge($config); $container->mailer->... $dumper = new PhpDumper($container); echo $dumper->dump();
  • 95. More about Dependency Injection http://fabien.potencier.org/article/17/on-php-5-3-lambda-functions-and-closures http://components.symfony-project.org/dependency-injection/ (5.2) http://github.com/fabpot/symfony/tree/master/src/Symfony/Components/DependencyInjection/(5.3) http://github.com/fabpot/pimple http://twittee.org/
  • 96. Remember, most of the time, you donā€™t need a Container to use Dependency Injection
  • 97. You can start to use and beneļ¬t from Dependency Injection today
  • 98. by implementing it in your projects by using externals libraries that already use DI without the need of a container
  • 99. Symfony Zend Framework ezComponents Doctrine Swift Mailer ā€¦
  • 100. Questions? My slides will be available on slideshare.com/fabpot
  • 101. Sensio S.A. 92-98, boulevard Victor Hugo 92 115 Clichy Cedex FRANCE TĆ©l. : +33 1 40 99 80 80 Contact Fabien Potencier fabien.potencier at sensio.com http://www.sensiolabs.com/ http://www.symfony-project.org/ http://fabien.potencier.org/