SlideShare a Scribd company logo
Dependency Injection
with PHP 5.3

Fabien Potencier
Fabien Potencier
•  Serial entrepreneur and developer by passion
•  Founder of Sensio (in 1998)
   –  A services and consulting company
      specialized in Web technologies
      and Internet marketing (France and USA)
   –  70 people
   –  Open-Source specialists
   –  Big corporate customers
   –  Consulting, training, development, web design, … and more
   –  Sponsor of a lot of Open-Source projects
      like symfony and Doctrine
Fabien Potencier
•  Creator and lead developer of symfony…
•  and creator and lead developer of some more OSS:
   –  symfony components
   –  Swift Mailer : Powerful component based mailing library for PHP
   –  Twig : Fexible, fast, and secure template language for PHP
   –  Pirum : Simple PEAR Channel Server Manager
   –  Sismo : PHP continuous integration server
   –  Lime : Easy to use unit testing library for PHP
   –  Twitto : A web framework in a tweet
   –  Twittee : A Dependency Injection Container in a tweet
   –  Pimple : A small PHP 5.3 dependency injection container
Fabien Potencier

•  Read my technical blog: http://fabien.potencier.org/

•  Follow me on Twitter: @fabpot

•  Fork my code on Github: http://github.com/fabpot/
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 first 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 different 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);
Configuration 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 different Storage strategies
       Configuration 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 fields. »
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 configures
     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
                   defined on the fly
                    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 the fastest framework
         for a “Hello World” app
(about 4-5 times faster than symfony 1.4)
Very flexible

Configuration 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 configuration
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 benefit 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
      …
symfony-live.com
         with Matthew Weier O’Pheinney




    I will reveal the first alpha release of Symfony 2.0!
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

Data structures and algorithms
Data structures and algorithmsData structures and algorithms
Data structures and algorithms
Julie Iskander
 
C++ Pointers And References
C++ Pointers And ReferencesC++ Pointers And References
C++ Pointers And References
verisan
 
pointer, virtual function and polymorphism
pointer, virtual function and polymorphismpointer, virtual function and polymorphism
pointer, virtual function and polymorphism
ramya marichamy
 
Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
Mario Fusco
 
Hashing
HashingHashing
Hashing
Ghaffar Khan
 
20.2 Java inheritance
20.2 Java inheritance20.2 Java inheritance
20.2 Java inheritance
Intro C# Book
 
Clean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionClean Code: Chapter 3 Function
Clean Code: Chapter 3 Function
Kent Huang
 
Introduction to Java 8
Introduction to Java 8Introduction to Java 8
Introduction to Java 8
Knoldus Inc.
 
Advanced Python : Decorators
Advanced Python : DecoratorsAdvanced Python : Decorators
Advanced Python : Decorators
Bhanwar Singh Meena
 
unit-1-dsa-hashing-2022_compressed-1-converted.pptx
unit-1-dsa-hashing-2022_compressed-1-converted.pptxunit-1-dsa-hashing-2022_compressed-1-converted.pptx
unit-1-dsa-hashing-2022_compressed-1-converted.pptx
BabaShaikh3
 
List in java
List in javaList in java
List in java
nitin kumar
 
Python Lambda Function
Python Lambda FunctionPython Lambda Function
Python Lambda Function
Md Soyaib
 
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
Philip Schwarz
 
Naked Performance With Clojure
Naked Performance With ClojureNaked Performance With Clojure
Naked Performance With Clojure
Metosin Oy
 
Iterarators and generators in python
Iterarators and generators in pythonIterarators and generators in python
Iterarators and generators in python
Sarfaraz Ghanta
 
Namespaces
NamespacesNamespaces
Namespaces
Sangeetha S
 
Function overloading and overriding
Function overloading and overridingFunction overloading and overriding
Function overloading and overriding
Rajab Ali
 
ΑΕΠΠ - Μάθημα 12
ΑΕΠΠ - Μάθημα 12ΑΕΠΠ - Μάθημα 12
ΑΕΠΠ - Μάθημα 12
Jonny Arvanitakis
 
Getters_And_Setters.pptx
Getters_And_Setters.pptxGetters_And_Setters.pptx
Getters_And_Setters.pptx
Kavindu Sachinthe
 
Python Κεφ. 1.5 συναρτήσεις
Python Κεφ. 1.5 συναρτήσειςPython Κεφ. 1.5 συναρτήσεις
Python Κεφ. 1.5 συναρτήσεις
Ιωάννου Γιαννάκης
 

What's hot (20)

Data structures and algorithms
Data structures and algorithmsData structures and algorithms
Data structures and algorithms
 
C++ Pointers And References
C++ Pointers And ReferencesC++ Pointers And References
C++ Pointers And References
 
pointer, virtual function and polymorphism
pointer, virtual function and polymorphismpointer, virtual function and polymorphism
pointer, virtual function and polymorphism
 
Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
 
Hashing
HashingHashing
Hashing
 
20.2 Java inheritance
20.2 Java inheritance20.2 Java inheritance
20.2 Java inheritance
 
Clean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionClean Code: Chapter 3 Function
Clean Code: Chapter 3 Function
 
Introduction to Java 8
Introduction to Java 8Introduction to Java 8
Introduction to Java 8
 
Advanced Python : Decorators
Advanced Python : DecoratorsAdvanced Python : Decorators
Advanced Python : Decorators
 
unit-1-dsa-hashing-2022_compressed-1-converted.pptx
unit-1-dsa-hashing-2022_compressed-1-converted.pptxunit-1-dsa-hashing-2022_compressed-1-converted.pptx
unit-1-dsa-hashing-2022_compressed-1-converted.pptx
 
List in java
List in javaList in java
List in java
 
Python Lambda Function
Python Lambda FunctionPython Lambda Function
Python Lambda Function
 
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
 
Naked Performance With Clojure
Naked Performance With ClojureNaked Performance With Clojure
Naked Performance With Clojure
 
Iterarators and generators in python
Iterarators and generators in pythonIterarators and generators in python
Iterarators and generators in python
 
Namespaces
NamespacesNamespaces
Namespaces
 
Function overloading and overriding
Function overloading and overridingFunction overloading and overriding
Function overloading and overriding
 
ΑΕΠΠ - Μάθημα 12
ΑΕΠΠ - Μάθημα 12ΑΕΠΠ - Μάθημα 12
ΑΕΠΠ - Μάθημα 12
 
Getters_And_Setters.pptx
Getters_And_Setters.pptxGetters_And_Setters.pptx
Getters_And_Setters.pptx
 
Python Κεφ. 1.5 συναρτήσεις
Python Κεφ. 1.5 συναρτήσειςPython Κεφ. 1.5 συναρτήσεις
Python Κεφ. 1.5 συναρτήσεις
 

Viewers also liked

Design pattern in Symfony2 - Nanos gigantium humeris insidentes
Design pattern in Symfony2 - Nanos gigantium humeris insidentesDesign pattern in Symfony2 - Nanos gigantium humeris insidentes
Design pattern in Symfony2 - Nanos gigantium humeris insidentes
Giulio De Donato
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
Fabien Potencier
 
Design patterns avec Symfony
Design patterns avec SymfonyDesign patterns avec Symfony
Design patterns avec Symfony
Mohammed Rhamnia
 
Dependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony Container
Diego Lewin
 
Ciklum Odessa PHP Saturday - Dependency Injection
Ciklum Odessa PHP Saturday - Dependency InjectionCiklum Odessa PHP Saturday - Dependency Injection
Ciklum Odessa PHP Saturday - Dependency Injection
Pavel Voznenko
 
Dependency Injection. Как сказать всё, не говоря ничего. Кожевников Дмитрий. ...
Dependency Injection. Как сказать всё, не говоря ничего. Кожевников Дмитрий. ...Dependency Injection. Как сказать всё, не говоря ничего. Кожевников Дмитрий. ...
Dependency Injection. Как сказать всё, не говоря ничего. Кожевников Дмитрий. ...
Dev2Dev
 
Dependency Injection Pattern in JavaScript, Speakers' Corner by Evgeny Dmitri...
Dependency Injection Pattern in JavaScript, Speakers' Corner by Evgeny Dmitri...Dependency Injection Pattern in JavaScript, Speakers' Corner by Evgeny Dmitri...
Dependency Injection Pattern in JavaScript, Speakers' Corner by Evgeny Dmitri...
Ciklum Minsk
 
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
Fabien Potencier
 
Dependency Injection in PHP
Dependency Injection in PHPDependency Injection in PHP
Dependency Injection in PHP
Kacper Gunia
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
Konstantin Kudryashov
 
Тестирование безопасности: PHP инъекция
Тестирование безопасности: PHP инъекцияТестирование безопасности: PHP инъекция
Тестирование безопасности: PHP инъекция
SQALab
 
Videography and Photography in the Church
Videography and Photography in the ChurchVideography and Photography in the Church
Videography and Photography in the Church
Concordia Technology Solutions
 
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
Fabien Potencier
 
Photography 102 - Master Your DSLR - San Diego Photography Classes
Photography 102 - Master Your DSLR - San Diego Photography Classes Photography 102 - Master Your DSLR - San Diego Photography Classes
Photography 102 - Master Your DSLR - San Diego Photography Classes
Jason Kirby
 
Lighting techniques for photography
Lighting techniques for photographyLighting techniques for photography
Lighting techniques for photography
JONESWILSON123
 
PHP Security
PHP SecurityPHP Security
PHP Security
manugoel2003
 
500 poses for photographing women a visual sourcebook for portrait photographers
500 poses for photographing women a visual sourcebook for portrait photographers500 poses for photographing women a visual sourcebook for portrait photographers
500 poses for photographing women a visual sourcebook for portrait photographers
Vinh Nguyen
 
Oops in PHP
Oops in PHPOops in PHP
Oops in PHP
Mindfire Solutions
 

Viewers also liked (18)

Design pattern in Symfony2 - Nanos gigantium humeris insidentes
Design pattern in Symfony2 - Nanos gigantium humeris insidentesDesign pattern in Symfony2 - Nanos gigantium humeris insidentes
Design pattern in Symfony2 - Nanos gigantium humeris insidentes
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
 
Design patterns avec Symfony
Design patterns avec SymfonyDesign patterns avec Symfony
Design patterns avec Symfony
 
Dependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony Container
 
Ciklum Odessa PHP Saturday - Dependency Injection
Ciklum Odessa PHP Saturday - Dependency InjectionCiklum Odessa PHP Saturday - Dependency Injection
Ciklum Odessa PHP Saturday - Dependency Injection
 
Dependency Injection. Как сказать всё, не говоря ничего. Кожевников Дмитрий. ...
Dependency Injection. Как сказать всё, не говоря ничего. Кожевников Дмитрий. ...Dependency Injection. Как сказать всё, не говоря ничего. Кожевников Дмитрий. ...
Dependency Injection. Как сказать всё, не говоря ничего. Кожевников Дмитрий. ...
 
Dependency Injection Pattern in JavaScript, Speakers' Corner by Evgeny Dmitri...
Dependency Injection Pattern in JavaScript, Speakers' Corner by Evgeny Dmitri...Dependency Injection Pattern in JavaScript, Speakers' Corner by Evgeny Dmitri...
Dependency Injection Pattern in JavaScript, Speakers' Corner by Evgeny Dmitri...
 
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
 
Dependency Injection in PHP
Dependency Injection in PHPDependency Injection in PHP
Dependency Injection in PHP
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
Тестирование безопасности: PHP инъекция
Тестирование безопасности: PHP инъекцияТестирование безопасности: PHP инъекция
Тестирование безопасности: PHP инъекция
 
Videography and Photography in the Church
Videography and Photography in the ChurchVideography and Photography in the Church
Videography and Photography in the Church
 
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
 
Photography 102 - Master Your DSLR - San Diego Photography Classes
Photography 102 - Master Your DSLR - San Diego Photography Classes Photography 102 - Master Your DSLR - San Diego Photography Classes
Photography 102 - Master Your DSLR - San Diego Photography Classes
 
Lighting techniques for photography
Lighting techniques for photographyLighting techniques for photography
Lighting techniques for photography
 
PHP Security
PHP SecurityPHP Security
PHP Security
 
500 poses for photographing women a visual sourcebook for portrait photographers
500 poses for photographing women a visual sourcebook for portrait photographers500 poses for photographing women a visual sourcebook for portrait photographers
500 poses for photographing women a visual sourcebook for portrait photographers
 
Oops in PHP
Oops in PHPOops in PHP
Oops in PHP
 

Similar to Dependency Injection with PHP 5.3

Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
Fabien Potencier
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010
Fabien Potencier
 
Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010
Fabien Potencier
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
Fabien Potencier
 
Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4
Fabien Potencier
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010
Fabien Potencier
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
Alexei 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
 
BEAR DI
BEAR DIBEAR DI
MUC - Moodle Universal Cache
MUC - Moodle Universal CacheMUC - Moodle Universal Cache
MUC - Moodle Universal Cache
Tim Hunt
 
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
Erick Hitter
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
Rifat Nabi
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
Jonathan Wage
 
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
SWIFTotter Solutions
 
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
Nate Abele
 
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 Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
Nate Abele
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
Nate Abele
 
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
Jeff Carouth
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
Nate Abele
 

Similar to Dependency Injection with PHP 5.3 (20)

Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010
 
Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010
 
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)
 
BEAR DI
BEAR DIBEAR DI
BEAR DI
 
MUC - Moodle Universal Cache
MUC - Moodle Universal CacheMUC - Moodle Universal Cache
MUC - Moodle Universal Cache
 
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
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
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
 
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
 
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 Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
 
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
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
 

More from Fabien Potencier

Varnish
VarnishVarnish
Look beyond PHP
Look beyond PHPLook beyond PHP
Look beyond PHP
Fabien Potencier
 
Caching on the Edge
Caching on the EdgeCaching on the Edge
Caching on the Edge
Fabien Potencier
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010
Fabien Potencier
 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
Fabien Potencier
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
Fabien Potencier
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
Fabien Potencier
 
Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010
Fabien Potencier
 
Caching on the Edge with Symfony2
Caching on the Edge with Symfony2Caching on the Edge with Symfony2
Caching on the Edge with Symfony2
Fabien Potencier
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2
Fabien Potencier
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
Fabien Potencier
 
Symfony Components
Symfony ComponentsSymfony Components
Symfony Components
Fabien Potencier
 
PHP 5.3 in practice
PHP 5.3 in practicePHP 5.3 in practice
PHP 5.3 in practice
Fabien Potencier
 
Symfony2 revealed
Symfony2 revealedSymfony2 revealed
Symfony2 revealed
Fabien 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.3
Fabien 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.3
Fabien Potencier
 
Symfony2 San Francisco Meetup 2009
Symfony2 San Francisco Meetup 2009Symfony2 San Francisco Meetup 2009
Symfony2 San Francisco Meetup 2009
Fabien Potencier
 
Symfony And Zend Framework Together 2009
Symfony And Zend Framework Together 2009Symfony And Zend Framework Together 2009
Symfony And Zend Framework Together 2009
Fabien 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 PHP
Fabien Potencier
 

More from Fabien Potencier (20)

Varnish
VarnishVarnish
Varnish
 
Look beyond PHP
Look beyond PHPLook beyond PHP
Look beyond PHP
 
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
 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010
 
Caching on the Edge with Symfony2
Caching on the Edge with Symfony2Caching on the Edge with Symfony2
Caching on the Edge with Symfony2
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
 
Symfony Components
Symfony ComponentsSymfony Components
Symfony Components
 
PHP 5.3 in practice
PHP 5.3 in practicePHP 5.3 in practice
PHP 5.3 in practice
 
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
 

Recently uploaded

Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
Zilliz
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
Neo4j
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
kumardaparthi1024
 
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial IntelligenceAI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
IndexBug
 
“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”
Claudio Di Ciccio
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
DianaGray10
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
SOFTTECHHUB
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
innovationoecd
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Paige Cruz
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
名前 です男
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
Pixlogix Infotech
 
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with SlackLet's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
shyamraj55
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
Adtran
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
Edge AI and Vision Alliance
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
Kumud Singh
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
Neo4j
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
panagenda
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
Neo4j
 

Recently uploaded (20)

Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
 
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial IntelligenceAI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
 
“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
 
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with SlackLet's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
 

Dependency Injection with PHP 5.3

  • 1. Dependency Injection with PHP 5.3 Fabien Potencier
  • 2. Fabien Potencier •  Serial entrepreneur and developer by passion •  Founder of Sensio (in 1998) –  A services and consulting company specialized in Web technologies and Internet marketing (France and USA) –  70 people –  Open-Source specialists –  Big corporate customers –  Consulting, training, development, web design, … and more –  Sponsor of a lot of Open-Source projects like symfony and Doctrine
  • 3. Fabien Potencier •  Creator and lead developer of symfony… •  and creator and lead developer of some more OSS: –  symfony components –  Swift Mailer : Powerful component based mailing library for PHP –  Twig : Fexible, fast, and secure template language for PHP –  Pirum : Simple PEAR Channel Server Manager –  Sismo : PHP continuous integration server –  Lime : Easy to use unit testing library for PHP –  Twitto : A web framework in a tweet –  Twittee : A Dependency Injection Container in a tweet –  Pimple : A small PHP 5.3 dependency injection container
  • 4. Fabien Potencier •  Read my technical blog: http://fabien.potencier.org/ •  Follow me on Twitter: @fabpot •  Fork my code on Github: http://github.com/fabpot/
  • 5. Dependency Injection A real world « web » example
  • 6. In most web applications, you need to manage the user preferences –  The user language –  Whether the user is authenticated or not –  The user credentials –  …
  • 7. This can be done with a User object –  setLanguage(), getLanguage() –  setAuthenticated(), isAuthenticated() –  addCredential(), hasCredential() –  ...
  • 8. The User information need to be persisted between HTTP requests We use the PHP session for the Storage
  • 9. class SessionStorage { function __construct($cookieName = 'PHP_SESS_ID') { session_name($cookieName); session_start(); } function set($key, $value) { $_SESSION[$key] = $value; } // ... }
  • 10. 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();
  • 11. 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
  • 13. Let’s understand why the first example is not a good idea
  • 14. I want to change the session cookie name
  • 15. 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();
  • 16. 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();
  • 17. class User { protected $storage; function __construct($sessionName) { $this->storage = new SessionStorage($sessionName); } } $user = new User('SESSION_ID'); Configure via User?
  • 18. 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?
  • 19. I want to change the session storage implementation Filesystem MySQL Memcached …
  • 20. 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();
  • 21. Now, the User depends on the Registry
  • 22. Instead of harcoding the Storage dependency inside the User class constructor Inject the Storage dependency in the User object
  • 23. class User { protected $storage; function __construct($storage) { $this->storage = $storage; } } $storage = new SessionStorage('SESSION_ID'); $user = new User($storage);
  • 24. What are the advantages?
  • 26. class User { protected $storage; function __construct($storage) { $this->storage = $storage; } } Use a different Storage engine $storage = new MySQLSessionStorage('SESSION_ID'); $user = new User($storage);
  • 28. class User { protected $storage; function __construct($storage) { $this->storage = $storage; } } Configuration is natural $storage = new MySQLSessionStorage('SESSION_ID'); $user = new User($storage);
  • 29. Wrap third-party classes (Interface / Adapter)
  • 30. class User { protected $storage; Add an interface function __construct(SessionStorageInterface $storage) { $this->storage = $storage; } } interface SessionStorageInterface { function get($key); function set($key, $value); }
  • 31. Mock the Storage object (for testing)
  • 32. 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; } }
  • 33. Use different Storage strategies Configuration becomes natural Wrap third-party classes (Interface / Adapter) Mock the Storage object (for testing) Easy without changing the User class
  • 34. « Dependency Injection is where components are given their dependencies through their constructors, methods, or directly into fields. » http://www.picocontainer.org/injection.html
  • 35. $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;
  • 36. A slightly more complex web example
  • 37. $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);
  • 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();
  • 40. 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();
  • 41. We need a Container Describes objects and their dependencies Instantiates and configures objects on-demand
  • 42. A container SHOULD be able to manage ANY PHP object (POPO) The objects MUST not know that they are managed by a container
  • 43. •  Parameters –  The SessionStorageInterface implementation we want to use (the class name) –  The session name •  Objects –  SessionStorage –  User •  Dependencies –  User depends on a SessionStorageInterface implementation
  • 44. Let’s build a simple container with PHP 5.3
  • 46. class Container { protected $parameters = array(); public function setParameter($key, $value) { $this->parameters[$key] = $value; } public function getParameter($key) { return $this->parameters[$key]; } }
  • 47. 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
  • 48. 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]; } }
  • 49. 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);
  • 51. We need a way to describe how to create objects, without actually instantiating anything! Anonymous functions to the rescue!
  • 52. Anonymous Functions / Lambdas A lambda is a function defined on the fly with no name function () { echo 'Hello world!'; };
  • 53. Anonymous Functions / Lambdas A lambda can be stored in a variable $hello = function () { echo 'Hello world!'; };
  • 54. Anonymous Functions / Lambdas And then it can be used as any other PHP callable $hello(); call_user_func($hello);
  • 55. Anonymous Functions / Lambdas You can also pass a lambda as an argument to a function or method function foo(Closure $func) { $func(); } foo($hello);
  • 56. 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');
  • 58. 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
  • 59. $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');
  • 60. 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]; } } }
  • 61. $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;
  • 63. For some objects, like the user, the container must always return the same instance
  • 64. spl_object_hash($container->user) !== spl_object_hash($container->user)
  • 65. $container->user = function ($c) { static $user; if (is_null($user)) { $user = new User($c->storage); } return $user; };
  • 66. spl_object_hash($container->user) === spl_object_hash($container->user)
  • 67. $container->user = $container->asShared(function ($c) { return new User($c->storage); });
  • 68. A closure is a lambda that remembers the context of its creation…
  • 69. 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'), );
  • 70. $mapper = function ($article) { return $article->getTitle(); }; $titles = array_map($mapper, $articles);
  • 71. $method = 'getTitle'; $mapper = function ($article) use($method) { return $article->$method(); }; $method = 'getAuthor'; $titles = array_map($mapper, $articles);
  • 72. $mapper = function ($method) { return function ($article) use($method) { return $article->$method(); }; };
  • 73. $titles = array_map($mapper('getTitle'), $articles); $authors = array_map($mapper('getAuthor'), $articles);
  • 74. $container->user = $container->asShared(function ($c) { return new User($c->storage); });
  • 75. function asShared(Closure $lambda) { return function ($container) use ($lambda) { static $object; if (is_null($object)) { $object = $lambda($container); } return $object; }; }
  • 76. 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]; } } }
  • 77. 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; }; } }
  • 78. I’m NOT advocating the usage of lambdas everywhere This presentation is about showing how they work on practical examples
  • 79. A DI Container does NOT manage ALL your objects
  • 80. Good rule of thumb: It manages “Global” objects Objects with only one instance (!= Singletons)
  • 81. LIKE a User, a Request, a database Connection, a Logger, …
  • 82. UNLIKE Model objects (a Product, a blog Post, …)
  • 84. Rock-solid implementation of a DIC in PHP 5.3
  • 85. At the core of the Symfony 2.0 framework … which is the fastest framework for a “Hello World” app (about 4-5 times faster than symfony 1.4)
  • 86. Very flexible Configuration in PHP, XML, YAML, or INI
  • 87. $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>
  • 88. <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 }
  • 89. Fast as hell The container can be “compiled” down to plain PHP code
  • 90. 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; } }
  • 91. Semantic configuration Thanks to an extension mechanism
  • 92. <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>
  • 93. <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>
  • 94. 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
  • 95. Everything is converted by the extension to plain services and parameters no overhead
  • 96. 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();
  • 97. 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/
  • 98. Remember, most of the time, you don’t need a Container to use Dependency Injection
  • 99. You can start to use and benefit from Dependency Injection today
  • 100. by implementing it in your projects by using externals libraries that already use DI without the need of a container
  • 101. Symfony Zend Framework ezComponents Doctrine Swift Mailer …
  • 102. symfony-live.com with Matthew Weier O’Pheinney I will reveal the first alpha release of Symfony 2.0!
  • 103. Questions? My slides will be available on slideshare.com/fabpot
  • 104. 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/