SlideShare una empresa de Scribd logo
1 de 103
Descargar para leer sin conexión
Dependency Injection
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()
{
$this->storage = new SessionStorage();
}
function setLanguage($language)
{
$this->storage->set('language', $language);
}
// ...
}
$user = new User();
Very easy
to use
Very hard to
customize
class User
{
protected $storage;
function __construct($storage)
{
$this->storage = $storage;
}
}
$storage = new SessionStorage();
$user = new User($storage);
Slightly more
difficult to use
Very easy to
customize
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()
{
$this->storage = new SessionStorage('SESSION_ID');
}
function setLanguage($language)
{
$this->storage->set('language', $language);
}
// ...
}
$user = new User();
Hardcode it in the
User class
class User
{
protected $storage;
function __construct()
{
$this->storage = new SessionStorage(STORAGE_SESSION_NAME);
}
}
define('STORAGE_SESSION_NAME', 'SESSION_ID');
$user = new User();
Add a global
configuration?
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()
{
$this->storage = Registry::get('session_storage');
}
}
$storage = new SessionStorage();
Registry::set('session_storage', $storage);
$user = new User();
Use a global
registry object?
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;
}
}
$storage = new MySQLSessionStorage('SESSION_ID');
$user = new User($storage);
Use a different
Storage engine
Configuration becomes natural
class User
{
protected $storage;
function __construct($storage)
{
$this->storage = $storage;
}
}
$storage = new MySQLSessionStorage('SESSION_ID');
$user = new User($storage);
Configuration
is natural
Wrap third-party classes (Interface / Adapter)
class User
{
protected $storage;
function __construct(SessionStorageInterface $storage)
{
$this->storage = $storage;
}
}
interface SessionStorageInterface
{
function get($key);
function set($key, $value);
}
Add an interface
Mock the Storage object (for testing)
class User
{
protected $storage;
function __construct(SessionStorageInterface $storage)
{
$this->storage = $storage;
}
}
class SessionStorageForTests implements SessionStorageInterface
{
protected $data = array();
static function set($key, $value)
{
self::$data[$key] = $value;
}
}
Mock the Session
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];
}
}
$container = new Container();
$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);
Decoupling
Customization
Objects creation
class Container
{
protected $parameters = array();
public function __set($key, $value)
{
$this->parameters[$key] = $value;
}
public function __get($key)
{
return $this->parameters[$key];
}
}
Using PHP
magic methods
$container = new Container();
$container->session_name = 'SESSION_ID';
$container->storage_class = 'SessionStorage';
$sessionStorage = new $container->storage_class($container->session_name);
$user = new User($sessionStorage);
Interface
is cleaner
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)
{
return $this->parameters[$key];
}
public function setService($key, Closure $service)
{
$this->objects[$key] = $service;
}
public function getService($key)
{
return $this->objects[$key]($this);
}
}
Store a lambda
able to create the
object on-demand
Ask the closure to create
the object and pass the
current Container
$container = new Container();
$container->session_name = 'SESSION_ID';
$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);
});
$user = $container->getService('user');
Creating the User
is now as easy as before
Description
class Container
{
protected $values = array();
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];
}
}
}
Simplify the code
$container = new Container();
$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;
Unified interface
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)
{
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];
}
}
}
Error management
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)
{
return function ($c) use ($callable)
{
static $object;
if (is_null($object))
{
$object = $callable($c);
}
return $object;
};
}
}
40 LOC for a fully-
featured container
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 flexible
Configuration in PHP, XML, YAML, or INI
$container = new Builder();
$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 }
message:
class: Message
arguments:
- @output
- { with_newline: true }
<container xmlns="http://symfony-project.org/schema/dic/services">
<services>
<service id="output" class="FancyOutput" />
<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 }
As fast as it can be
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" />
<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>
auto-completion
and validation
with XSD
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
…
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/

Más contenido relacionado

La actualidad más candente

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 FrameworksNate 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 State of Lithium
The State of LithiumThe State of Lithium
The State of LithiumNate Abele
 
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
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of LithiumNate Abele
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010Fabien Potencier
 
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
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteLeonardo Proietti
 
Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8PrinceGuru MS
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Leonardo Proietti
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixturesBill Chang
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
 
PHP Data Objects
PHP Data ObjectsPHP Data Objects
PHP Data ObjectsWez Furlong
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design PatternsHugo Hamon
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 

La actualidad más candente (20)

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
 
Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010
 
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 State of Lithium
The State of LithiumThe State of Lithium
The State of Lithium
 
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
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
 
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
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 
Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
PHP Data Objects
PHP Data ObjectsPHP Data Objects
PHP Data Objects
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 

Destacado

Advanced Date/Time Handling with PHP
Advanced Date/Time Handling with PHPAdvanced Date/Time Handling with PHP
Advanced Date/Time Handling with PHPAnis Berejeb
 
Continuous Improvement in PHP Projects - PHP UK Conference 2011
Continuous Improvement in PHP Projects - PHP UK Conference 2011Continuous Improvement in PHP Projects - PHP UK Conference 2011
Continuous Improvement in PHP Projects - PHP UK Conference 2011Mayflower GmbH
 
Symfony2 Components - The Event Dispatcher
Symfony2 Components - The Event DispatcherSymfony2 Components - The Event Dispatcher
Symfony2 Components - The Event DispatcherSarah El-Atm
 
symfony 1.1 goodness (Dutch PHP Conference 2008)
symfony 1.1 goodness (Dutch PHP Conference 2008)symfony 1.1 goodness (Dutch PHP Conference 2008)
symfony 1.1 goodness (Dutch PHP Conference 2008)Fabien Potencier
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 WorldFabien Potencier
 
Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Fabien 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
 
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
 
English Parts Of Speech
English Parts Of SpeechEnglish Parts Of Speech
English Parts Of Speechguesta684c8b
 
Secret History of Silicon Valley - Master Slide Deck
Secret History of Silicon Valley - Master Slide DeckSecret History of Silicon Valley - Master Slide Deck
Secret History of Silicon Valley - Master Slide DeckStanford University
 

Destacado (20)

Look beyond PHP
Look beyond PHPLook beyond PHP
Look beyond PHP
 
Varnish
VarnishVarnish
Varnish
 
PHP 5.3 in practice
PHP 5.3 in practicePHP 5.3 in practice
PHP 5.3 in practice
 
Advanced Date/Time Handling with PHP
Advanced Date/Time Handling with PHPAdvanced Date/Time Handling with PHP
Advanced Date/Time Handling with PHP
 
Continuous Improvement in PHP Projects - PHP UK Conference 2011
Continuous Improvement in PHP Projects - PHP UK Conference 2011Continuous Improvement in PHP Projects - PHP UK Conference 2011
Continuous Improvement in PHP Projects - PHP UK Conference 2011
 
Symfony2 Components - The Event Dispatcher
Symfony2 Components - The Event DispatcherSymfony2 Components - The Event Dispatcher
Symfony2 Components - The Event Dispatcher
 
symfony 1.1 goodness (Dutch PHP Conference 2008)
symfony 1.1 goodness (Dutch PHP Conference 2008)symfony 1.1 goodness (Dutch PHP Conference 2008)
symfony 1.1 goodness (Dutch PHP Conference 2008)
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
 
Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010
 
Caching on the Edge with Symfony2
Caching on the Edge with Symfony2Caching on the Edge with Symfony2
Caching on the Edge with Symfony2
 
Caching on the Edge
Caching on the EdgeCaching on the Edge
Caching on the Edge
 
Symfony Components
Symfony ComponentsSymfony Components
Symfony Components
 
Symfony Best Practices
Symfony Best PracticesSymfony Best Practices
Symfony Best Practices
 
30 Symfony Best Practices
30 Symfony Best Practices30 Symfony Best Practices
30 Symfony Best Practices
 
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
 
English Parts Of Speech
English Parts Of SpeechEnglish Parts Of Speech
English Parts Of Speech
 
Secret History of Silicon Valley - Master Slide Deck
Secret History of Silicon Valley - Master Slide DeckSecret History of Silicon Valley - Master Slide Deck
Secret History of Silicon Valley - Master Slide Deck
 
Culture
CultureCulture
Culture
 

Similar a Dependency injection-zendcon-2010

Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8Alexei Gorobets
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Drupal 8 Services And Dependency Injection
Drupal 8 Services And Dependency InjectionDrupal 8 Services And Dependency Injection
Drupal 8 Services And Dependency InjectionPhilip Norton
 
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
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Developmentjsmith92
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony AppsKris Wallsmith
 
Lecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptxLecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptxDavidLazar17
 
Modularity and Layered Data Model
Modularity and Layered Data ModelModularity and Layered Data Model
Modularity and Layered Data ModelAttila Jenei
 
Demystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHPDemystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHPAlena Holligan
 
Easy rest service using PHP reflection api
Easy rest service using PHP reflection apiEasy rest service using PHP reflection api
Easy rest service using PHP reflection apiMatthieu Aubry
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsMichael Peacock
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency InjectionRifat Nabi
 
Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016Alena Holligan
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hackingJeroen van Dijk
 

Similar a Dependency injection-zendcon-2010 (20)

Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
BEAR DI
BEAR DIBEAR DI
BEAR DI
 
PHP pod mikroskopom
PHP pod mikroskopomPHP pod mikroskopom
PHP pod mikroskopom
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Drupal 8 Services And Dependency Injection
Drupal 8 Services And Dependency InjectionDrupal 8 Services And Dependency Injection
Drupal 8 Services And Dependency Injection
 
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)
 
Oops in php
Oops in phpOops in php
Oops in php
 
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
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
Solid principles
Solid principlesSolid principles
Solid principles
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
Lecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptxLecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptx
 
Modularity and Layered Data Model
Modularity and Layered Data ModelModularity and Layered Data Model
Modularity and Layered Data Model
 
Demystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHPDemystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHP
 
Easy rest service using PHP reflection api
Easy rest service using PHP reflection apiEasy rest service using PHP reflection api
Easy rest service using PHP reflection api
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 

Más de 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.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
 

Más de Fabien Potencier (10)

Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
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)
 

Último

Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 

Último (20)

Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 

Dependency injection-zendcon-2010