SlideShare a Scribd company logo
IoC with PHP
     Chris Weldon
  Dallas TechFest 2011
Before We Begin


                                            http://bit.ly/rf1pxR


git://github.com/neraath/ioc-php-talk.git
Your Guide: Chris Weldon

•   Fightin’ Texas Aggie

•   .Net and PHP Developer

•   UNIX and Windows Sysadmin

•   Senior Consultant at Improving Enterprises

•   Contact Me: chris@chrisweldon.net
Agile, Microsoft, Open Technologies, UX
Applied Training, Coaching, Mentoring
Certified Consulting
Rural Sourcing
Recruiting Services
Before We Get to IoC...
<?php
class Authenticator {
    private $_repository;

    public function __construct() {
        $this->_repository = new DataAccessLayer();
    }

    public function authenticate($username, $password) {
        $hashedPassword = md5($password);
        $user = $this->_repository->findByUsernameAndPassword(
            $username, $hashedPassword);
        return $user === null;
    }
}
What are the problems?
What are the problems?

•   Strongly coupled to DataAccessLayer
What are the problems?

•   Strongly coupled to DataAccessLayer
                                                    Authenticator
                                                authenticate() : bool




                                                  DataAccessLayer
                                          findByUsernameAndPassword : array
What are the problems?

•   Strongly coupled to DataAccessLayer

•
                                                    Authenticator
    Very inflexible                              authenticate() : bool




                                                  DataAccessLayer
                                          findByUsernameAndPassword : array
What are the problems?

•   Strongly coupled to DataAccessLayer

•
                                                    Authenticator
    Very inflexible                              authenticate() : bool



•   How to configure DataAccessLayer?
                                                  DataAccessLayer
                                          findByUsernameAndPassword : array
What are the problems?

•   Strongly coupled to DataAccessLayer

•
                                                    Authenticator
    Very inflexible                              authenticate() : bool



•   How to configure DataAccessLayer?

    •
                                                  DataAccessLayer
        Let it read configs?               findByUsernameAndPassword : array
What are the problems?

•   Strongly coupled to DataAccessLayer

•
                                                    Authenticator
    Very inflexible                              authenticate() : bool



•   How to configure DataAccessLayer?

    •
                                                  DataAccessLayer
        Let it read configs?               findByUsernameAndPassword : array


•   How to test the Authenticator?
Let’s solve it


•   What are our goals?

    •   Decrease coupling

    •   Increase configurability
<?php
interface IUserRepository {
    function findByUsernameAndPassword($username, $password);
}
class DataAccessLayer implements IUserRepository {
    private $_configParams;
    private $_database;

    public function __construct(array $configParams) {
        $this->_configParams = $configParams;
        $this->_database = Zend_Db::factory('Pdo_Mysql', $this->_configParams);
    }

    public function findByUsernameAndPassword($username, $password) {
        $query = 'SELECT * FROM users WHERE username = ? AND password = ?';
        $result = $this->_database->fetchAll($query, $username, $password);
        return $result;
    }
}
Our Updated Authenticator
<?php
class Authenticator {
    private $_repository;

    public function __construct(IUserRepository $repository) {
        $this->_repository = $repository;
    }

    public function authenticate($username, $password) {
        $hashedPassword = md5($password);
        $user = $this->_repository->findByUsernameAndPassword(
            $username, $hashedPassword);
        return $user === null;
    }
}
Time to Consume
<?php
class LoginController {
    public function login($username, $password) {
        $configuration = Zend_Registry::get('dbconfig');
        $dal = new DataAccessLayer($configuration);
        $authenticator = new Authenticator($dal);
        if ($authenticator->authenticate($username, $password)) {
            // Do something to log the user in.
        }
    }
}
Goal Recap


•   What were our goals?

    •   Decrease coupling

    •   Increase configurability
Goal Recap


•   What were our goals?

    •   Decrease coupling

    •   Increase configurability
Goal Recap


•   What were our goals?

    •   Decrease coupling

    •   Increase configurability
What You Saw Was IoC
•   Inversion of Control changes direction of responsibility

    •   Someone else responsible for creating and providing my
        dependencies

    •   Most commonly applied pattern: Dependency Injection

    •   Follows Dependency Inversion Principle from SOLID

•   Culture War: IoC vs. DI vs. Naming vs. Principles vs. Ideology
Dependency Inversion


•   “High-level modules should not depend upon low level modules. They
    should depend upon abstractions.

•   “Abstractions should not depend upon details. Details should depend
    upon abstractions.”
                                                           Robert Martin
Let’s Draw
Let’s Draw

          Authenticator
      authenticate() : bool




        DataAccessLayer
findByUsernameAndPassword : array
Let’s Draw

          Authenticator
      authenticate() : bool




        DataAccessLayer
findByUsernameAndPassword : array
Let’s Draw
                                                  Authenticator
                                              authenticate() : bool

          Authenticator
      authenticate() : bool

                                                 IUserRepository
                                        findByUsernameAndPassword : array

        DataAccessLayer
findByUsernameAndPassword : array

                                                DataAccessLayer
                                        findByUsernameAndPassword : array
Benefit: Flexibility
<?php
class WebServiceUserRepository implements IUserRepository {
    public function findByUsernameAndPassword($username, $password) {
        // Fetch our user through JSON or SOAP
    }
}

class OAuthRepository implements IUserRepository {
    public function findByUsernameAndPassword($username, $password) {
        // Connect to your favorite OAuth provider
    }
}
Benefit: Testable
<?php
class WhenAuthenticating extends PHPUnit_Framework_TestCase {
    public function testGivenInvalidUsernameAndPasswordShouldReturnFalse() {
        $stub = $this->getMock('IUserRepository');
        $stub->expects($this->any())
             ->method('findByUsernameAndPassword')
             ->will($this->returnValue(null));

        $authenticator = new Authenticator($stub);

        $this->assertFalse($authenticator->authenticate('user', 'pass'));
    }
}
Dependency Injection

•   Now we can inject our dependencies to our consumer classes

•   Still requires some other class to be tightly coupled to both of those

•   Need a container that can help abstract the relationship between the
    interface and implementation
<?php
class UserRepositoryContainer {
    /** @return IUserRepository **/
    public function getRepository() {
        $container = new DataAccessLayer(array(
            'dsn' => 'mysql://localhost/database',
            'username' => 'user',
            'password' => 'pass'
        ));

        return $container;
    }
}

class LoginController {
    public function login($username, $password) {
        $container = new UserRepositoryContainer();
        $repository = $container->getRepository();
        $authenticator = new Authenticator($repository);
        // ...
    }
}
Container Woes

•   No uniform interface by which to access services

•   Still tightly coupled with dependencies

•   Configurability of the container difficult

•   How to auto-inject dependency for configured consumer classes?
Symfony Dependency Injection
                 Container

•   Two Ways to Setup and Use sfServiceContainer

    •   Create subclass

    •   Manual registration via code or config
sfServiceContainer Subclass

<?php
class UserRepositoryContainer extends sfServiceContainer {
    protected function getUserRepositoryService() {
        $container = new DataAccessLayer($this['repository.config']);
        return $container;
    }
}
Consuming the Container
<?php
class LoginController {
    public function login($username, $password) {
        $configuration = Zend_Registry::get('dbconfig');

        $container = new UserRepositoryContainer(array(
            'repository.config' => $configuration
        ));
        $repository = $container->userRepository;

        $authenticator = new Authenticator($repository);
        if ($authenticator->authenticate($username, $password)) {
            // Do something to log the user in.
        }
    }
}
That’s Pretty Nice

•   Configurability a lot easier

•   Uniform interface for accessing services

•   How does this scale when there are lots of dependencies?

•   Aren’t we still coupling the container to the implementation at
    compile time?
The Builder

•   Provides a uniform way of describing services, without custom
    containers

•   For each service description, we have the flexibility to configure an
    object:

    •   At instantiation (Constructor Injection)

    •   Post-instantiation (Setter/Method Injection)
How to Describe a Service

•   Code-based or Config-based

    •   Code-based allows for run-time changing of injection parameters

    •   Config-based provides a way to change parameters between
        environments with no code changes

    •   Not mutually exclusive
Code-Based Description
<?php
// Imagine this is a bootstrap file.
$configuration = Zend_Registry::get('dbconfig');

$builder = new sfServiceContainerBuilder();

$builder->register('user_repository', 'DataAccessLayer')
        ->addArgument($configuration)
        // OR ->addArgument('%repository.config%') from earlier
        ->setShared(false);

$builder->register('authenticator', 'Authenticator')
        ->addArgument(new sfServiceReference('user_repository'));

Zend_Registry::set('di_container', $builder);
Config-Based Description
<?xml version="1.0" ?>
<container xmlns="http://symfony-project.org/2.0/container">
  <parameters>
    <parameter key="user_repository.dsn">mysql://localhost/database</parameter>
    <parameter key="user_repository.username">username</parameter>
    <parameter key="user_repository.password">password</parameter>
  </parameters>
  <services>
    <service id="user_repository" class="DataAccessLayer" shared="false">
      <argument type="collection">
        <argument key="dsn">%user_repository.dsn%</argument>
        <argument key="username">%user_repository.username%</argument>
        <argument key="password">%user_repository.password%</argument>
      </argument>
    </service>
    <service id="authenticator" class="Authenticator">
      <argument type="service" id="user_repository" />
    </service>
  </services>
</container>
Loading the Config

<?php
// Imagine this is a bootstrap file.
$builder = new sfServiceContainerBuilder();

$loader = new sfServiceContainerLoaderFileXml($builder);
$loader->load('/pathTo/services.xml');

Zend_Registry::set('di_container', $builder);
Using the Container

<?php
class LoginController {
    public function login($username, $password) {
        $container = Zend_Registry::get('di_container');
        $authenticator = $container->authenticator;
        if ($authenticator->authenticate($username, $password)) {
            // Do something to log the user in.
        }
    }
}
High Level Picture
        DataAccessLayer
findByUsernameAndPassword : array




         IUserRepository
findByUsernameAndPassword : array
                                     sfServiceContainerBuilder
                                   getService : object
                                   setService : void
                                   hasService : bool
            Authenticator
authenticate() : bool




            IAuthenticator
authenticate() : bool



                                     sfServiceContainerInterface
                                   getService : object
           LoginController         setService : void
        login() : void             hasService : bool
When to Use a DI Container
When to Use a DI Container

•   Not for model objects (e.g. Orders, Documents, etc.)
When to Use a DI Container

•   Not for model objects (e.g. Orders, Documents, etc.)

•   Great for resource requirements (e.g. repositories, loggers, etc.)
When to Use a DI Container

•   Not for model objects (e.g. Orders, Documents, etc.)

•   Great for resource requirements (e.g. repositories, loggers, etc.)

•   Really great for plugin-type architecture
When to Use a DI Container

•   Not for model objects (e.g. Orders, Documents, etc.)

•   Great for resource requirements (e.g. repositories, loggers, etc.)

•   Really great for plugin-type architecture

•   But not necessary to use Dependency Injection!
Other Considerations
Other Considerations

•   Learning curve
Other Considerations

•   Learning curve

•   Tracking dependencies
Other Considerations

•   Learning curve

•   Tracking dependencies

•   Dependency changes
Other Considerations

•   Learning curve

•   Tracking dependencies

•   Dependency changes

•   Setter/method vs. constructor injection
Service Lifetimes


•   setShared() allows you to specify context persistence

    •   If shared, acts like a singleton

    •   Useful if construction is expensive or state persistence required
Let’s Code
Thank You!


                                            http://bit.ly/rf1pxR


git://github.com/neraath/ioc-php-talk.git

More Related Content

What's hot

Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)
Yevgeniy Brikman
 
Cloud Native Identity with SPIFFE
Cloud Native Identity with SPIFFECloud Native Identity with SPIFFE
Cloud Native Identity with SPIFFE
Prabath Siriwardena
 
Intro to JavaScript
Intro to JavaScriptIntro to JavaScript
Intro to JavaScript
Yakov Fain
 
Domain Driven Design using Laravel
Domain Driven Design using LaravelDomain Driven Design using Laravel
Domain Driven Design using Laravel
wajrcs
 
Hibernate training
Hibernate trainingHibernate training
Hibernate training
TechFerry
 
Data Validation models
Data Validation modelsData Validation models
Data Validation models
Marcin Czarnecki
 
Recipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with XtendRecipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with Xtend
Karsten Thoms
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
scidept
 
AspMVC4 start101
AspMVC4 start101AspMVC4 start101
AspMVC4 start101
Rich Helton
 
Better Testing With PHP Unit
Better Testing With PHP UnitBetter Testing With PHP Unit
Better Testing With PHP Unit
sitecrafting
 
Spring training
Spring trainingSpring training
Spring training
TechFerry
 
Code Generation idioms with Xtend
Code Generation idioms with XtendCode Generation idioms with Xtend
Code Generation idioms with Xtend
Holger Schill
 
Connect.Tech- Enhancing Your Workflow With Xcode Source Editor Extensions
Connect.Tech- Enhancing Your Workflow With Xcode Source Editor ExtensionsConnect.Tech- Enhancing Your Workflow With Xcode Source Editor Extensions
Connect.Tech- Enhancing Your Workflow With Xcode Source Editor Extensions
stable|kernel
 
Apex Code Analysis Using the Tooling API and Canvas
Apex Code Analysis Using the Tooling API and CanvasApex Code Analysis Using the Tooling API and Canvas
Apex Code Analysis Using the Tooling API and Canvas
Salesforce Developers
 
ExtJs Basic Part-1
ExtJs Basic Part-1ExtJs Basic Part-1
ExtJs Basic Part-1
Mindfire Solutions
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
ColdFusionConference
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016
CiaranMcNulty
 
Web API with ASP.NET MVC by Software development company in india
Web API with ASP.NET  MVC  by Software development company in indiaWeb API with ASP.NET  MVC  by Software development company in india
Web API with ASP.NET MVC by Software development company in india
iFour Institute - Sustainable Learning
 
TangoWithDjango - ch8
TangoWithDjango - ch8TangoWithDjango - ch8
TangoWithDjango - ch8
Asika Kuo
 
2007 Zend Con Mvc
2007 Zend Con Mvc2007 Zend Con Mvc
2007 Zend Con Mvc
Pablo Morales
 

What's hot (20)

Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)
 
Cloud Native Identity with SPIFFE
Cloud Native Identity with SPIFFECloud Native Identity with SPIFFE
Cloud Native Identity with SPIFFE
 
Intro to JavaScript
Intro to JavaScriptIntro to JavaScript
Intro to JavaScript
 
Domain Driven Design using Laravel
Domain Driven Design using LaravelDomain Driven Design using Laravel
Domain Driven Design using Laravel
 
Hibernate training
Hibernate trainingHibernate training
Hibernate training
 
Data Validation models
Data Validation modelsData Validation models
Data Validation models
 
Recipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with XtendRecipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with Xtend
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 
AspMVC4 start101
AspMVC4 start101AspMVC4 start101
AspMVC4 start101
 
Better Testing With PHP Unit
Better Testing With PHP UnitBetter Testing With PHP Unit
Better Testing With PHP Unit
 
Spring training
Spring trainingSpring training
Spring training
 
Code Generation idioms with Xtend
Code Generation idioms with XtendCode Generation idioms with Xtend
Code Generation idioms with Xtend
 
Connect.Tech- Enhancing Your Workflow With Xcode Source Editor Extensions
Connect.Tech- Enhancing Your Workflow With Xcode Source Editor ExtensionsConnect.Tech- Enhancing Your Workflow With Xcode Source Editor Extensions
Connect.Tech- Enhancing Your Workflow With Xcode Source Editor Extensions
 
Apex Code Analysis Using the Tooling API and Canvas
Apex Code Analysis Using the Tooling API and CanvasApex Code Analysis Using the Tooling API and Canvas
Apex Code Analysis Using the Tooling API and Canvas
 
ExtJs Basic Part-1
ExtJs Basic Part-1ExtJs Basic Part-1
ExtJs Basic Part-1
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016
 
Web API with ASP.NET MVC by Software development company in india
Web API with ASP.NET  MVC  by Software development company in indiaWeb API with ASP.NET  MVC  by Software development company in india
Web API with ASP.NET MVC by Software development company in india
 
TangoWithDjango - ch8
TangoWithDjango - ch8TangoWithDjango - ch8
TangoWithDjango - ch8
 
2007 Zend Con Mvc
2007 Zend Con Mvc2007 Zend Con Mvc
2007 Zend Con Mvc
 

Viewers also liked

Ioc & in direction
Ioc & in directionIoc & in direction
Ioc & in direction
育汶 郭
 
2007 5 30 肖镜辉 统计语言模型简介
2007 5 30 肖镜辉 统计语言模型简介2007 5 30 肖镜辉 统计语言模型简介
2007 5 30 肖镜辉 统计语言模型简介
xceman
 
Stub you!
Stub you!Stub you!
Stub you!
Andrea Giuliano
 
PHP Unit-Testing With Doubles
PHP Unit-Testing With DoublesPHP Unit-Testing With Doubles
PHP Unit-Testing With Doubles
Mihail Irintchev
 
PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くために
Yuya Takeyama
 
Zensations Drupal 8 GraphQL Presentation 2015
Zensations Drupal 8 GraphQL Presentation 2015Zensations Drupal 8 GraphQL Presentation 2015
Zensations Drupal 8 GraphQL Presentation 2015
Zensations GmbH
 
PHPUnit 入門介紹
PHPUnit 入門介紹PHPUnit 入門介紹
PHPUnit 入門介紹
Jace Ju
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentation
Thanh Robi
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
Michelangelo van Dam
 
Jmeter Performance Testing
Jmeter Performance TestingJmeter Performance Testing
Jmeter Performance Testing
Atul Pant
 
Di – ioc (ninject)
Di – ioc (ninject)Di – ioc (ninject)
Di – ioc (ninject)
ZealousysDev
 
Advanced PHPUnit Testing
Advanced PHPUnit TestingAdvanced PHPUnit Testing
Advanced PHPUnit Testing
Mike Lively
 

Viewers also liked (12)

Ioc & in direction
Ioc & in directionIoc & in direction
Ioc & in direction
 
2007 5 30 肖镜辉 统计语言模型简介
2007 5 30 肖镜辉 统计语言模型简介2007 5 30 肖镜辉 统计语言模型简介
2007 5 30 肖镜辉 统计语言模型简介
 
Stub you!
Stub you!Stub you!
Stub you!
 
PHP Unit-Testing With Doubles
PHP Unit-Testing With DoublesPHP Unit-Testing With Doubles
PHP Unit-Testing With Doubles
 
PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くために
 
Zensations Drupal 8 GraphQL Presentation 2015
Zensations Drupal 8 GraphQL Presentation 2015Zensations Drupal 8 GraphQL Presentation 2015
Zensations Drupal 8 GraphQL Presentation 2015
 
PHPUnit 入門介紹
PHPUnit 入門介紹PHPUnit 入門介紹
PHPUnit 入門介紹
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentation
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
 
Jmeter Performance Testing
Jmeter Performance TestingJmeter Performance Testing
Jmeter Performance Testing
 
Di – ioc (ninject)
Di – ioc (ninject)Di – ioc (ninject)
Di – ioc (ninject)
 
Advanced PHPUnit Testing
Advanced PHPUnit TestingAdvanced PHPUnit Testing
Advanced PHPUnit Testing
 

Similar to IoC with PHP

Implementing access control with zend framework
Implementing access control with zend frameworkImplementing access control with zend framework
Implementing access control with zend framework
George Mihailov
 
Third Party Auth in WebObjects
Third Party Auth in WebObjectsThird Party Auth in WebObjects
Third Party Auth in WebObjects
WO Community
 
Becoming a better WordPress Developer
Becoming a better WordPress DeveloperBecoming a better WordPress Developer
Becoming a better WordPress Developer
Joey Kudish
 
Java EE 8 security and JSON binding API
Java EE 8 security and JSON binding APIJava EE 8 security and JSON binding API
Java EE 8 security and JSON binding API
Alex Theedom
 
Building Better Applications with Data::Manager
Building Better Applications with Data::ManagerBuilding Better Applications with Data::Manager
Building Better Applications with Data::Manager
Jay Shirley
 
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)
Sirar Salih
 
10 Rules for Safer Code
10 Rules for Safer Code10 Rules for Safer Code
10 Rules for Safer Code
Quang Ngoc
 
Persistant Cookies and LDAP Injection
Persistant Cookies and LDAP InjectionPersistant Cookies and LDAP Injection
Persistant Cookies and LDAP Injection
MaulikLakhani
 
10 Rules for Safer Code [Odoo Experience 2016]
10 Rules for Safer Code [Odoo Experience 2016]10 Rules for Safer Code [Odoo Experience 2016]
10 Rules for Safer Code [Odoo Experience 2016]
Olivier Dony
 
Simple Web Development in Java
Simple Web Development in JavaSimple Web Development in Java
Simple Web Development in Java
Vincent Tencé
 
Jakość dostarczanego oprogramowania oparta o testy
Jakość dostarczanego oprogramowania oparta o testyJakość dostarczanego oprogramowania oparta o testy
Jakość dostarczanego oprogramowania oparta o testy
Paweł Tekliński
 
Security in laravel
Security in laravelSecurity in laravel
Security in laravel
Sayed Ahmed
 
Code your Own: Authentication Provider for Blackboard Learn
Code your Own: Authentication Provider for Blackboard LearnCode your Own: Authentication Provider for Blackboard Learn
Code your Own: Authentication Provider for Blackboard Learn
Dan Rinzel
 
Real World MVC
Real World MVCReal World MVC
Real World MVC
James Johnson
 
State of the art authentication mit Java EE 8
State of the art authentication mit Java EE 8State of the art authentication mit Java EE 8
State of the art authentication mit Java EE 8
OPEN KNOWLEDGE GmbH
 
STATE OF THE ART AUTHENTICATION MIT JAVA EE 8
STATE OF THE ART AUTHENTICATION MIT JAVA EE 8STATE OF THE ART AUTHENTICATION MIT JAVA EE 8
STATE OF THE ART AUTHENTICATION MIT JAVA EE 8
OPEN KNOWLEDGE GmbH
 
Phactory
PhactoryPhactory
Phactory
chriskite
 
Authentication with zend framework
Authentication with zend frameworkAuthentication with zend framework
Authentication with zend framework
George Mihailov
 
Javascript Php Crud
Javascript Php CrudJavascript Php Crud
Javascript Php Crud
danielbertrand
 
devise tutorial - 2011 rubyconf taiwan
devise tutorial - 2011 rubyconf taiwandevise tutorial - 2011 rubyconf taiwan
devise tutorial - 2011 rubyconf taiwan
Tse-Ching Ho
 

Similar to IoC with PHP (20)

Implementing access control with zend framework
Implementing access control with zend frameworkImplementing access control with zend framework
Implementing access control with zend framework
 
Third Party Auth in WebObjects
Third Party Auth in WebObjectsThird Party Auth in WebObjects
Third Party Auth in WebObjects
 
Becoming a better WordPress Developer
Becoming a better WordPress DeveloperBecoming a better WordPress Developer
Becoming a better WordPress Developer
 
Java EE 8 security and JSON binding API
Java EE 8 security and JSON binding APIJava EE 8 security and JSON binding API
Java EE 8 security and JSON binding API
 
Building Better Applications with Data::Manager
Building Better Applications with Data::ManagerBuilding Better Applications with Data::Manager
Building Better Applications with Data::Manager
 
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)
 
10 Rules for Safer Code
10 Rules for Safer Code10 Rules for Safer Code
10 Rules for Safer Code
 
Persistant Cookies and LDAP Injection
Persistant Cookies and LDAP InjectionPersistant Cookies and LDAP Injection
Persistant Cookies and LDAP Injection
 
10 Rules for Safer Code [Odoo Experience 2016]
10 Rules for Safer Code [Odoo Experience 2016]10 Rules for Safer Code [Odoo Experience 2016]
10 Rules for Safer Code [Odoo Experience 2016]
 
Simple Web Development in Java
Simple Web Development in JavaSimple Web Development in Java
Simple Web Development in Java
 
Jakość dostarczanego oprogramowania oparta o testy
Jakość dostarczanego oprogramowania oparta o testyJakość dostarczanego oprogramowania oparta o testy
Jakość dostarczanego oprogramowania oparta o testy
 
Security in laravel
Security in laravelSecurity in laravel
Security in laravel
 
Code your Own: Authentication Provider for Blackboard Learn
Code your Own: Authentication Provider for Blackboard LearnCode your Own: Authentication Provider for Blackboard Learn
Code your Own: Authentication Provider for Blackboard Learn
 
Real World MVC
Real World MVCReal World MVC
Real World MVC
 
State of the art authentication mit Java EE 8
State of the art authentication mit Java EE 8State of the art authentication mit Java EE 8
State of the art authentication mit Java EE 8
 
STATE OF THE ART AUTHENTICATION MIT JAVA EE 8
STATE OF THE ART AUTHENTICATION MIT JAVA EE 8STATE OF THE ART AUTHENTICATION MIT JAVA EE 8
STATE OF THE ART AUTHENTICATION MIT JAVA EE 8
 
Phactory
PhactoryPhactory
Phactory
 
Authentication with zend framework
Authentication with zend frameworkAuthentication with zend framework
Authentication with zend framework
 
Javascript Php Crud
Javascript Php CrudJavascript Php Crud
Javascript Php Crud
 
devise tutorial - 2011 rubyconf taiwan
devise tutorial - 2011 rubyconf taiwandevise tutorial - 2011 rubyconf taiwan
devise tutorial - 2011 rubyconf taiwan
 

More from Chris Weldon

Keat presentation
Keat presentationKeat presentation
Keat presentation
Chris Weldon
 
REST Easy - Building RESTful Services in Zend Framework
REST Easy - Building RESTful Services in Zend FrameworkREST Easy - Building RESTful Services in Zend Framework
REST Easy - Building RESTful Services in Zend Framework
Chris Weldon
 
Beyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver SoftwareBeyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver Software
Chris Weldon
 
SOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO ProprietySOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO Propriety
Chris Weldon
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
Chris Weldon
 
Unit Testing in SharePoint 2010
Unit Testing in SharePoint 2010Unit Testing in SharePoint 2010
Unit Testing in SharePoint 2010
Chris Weldon
 
PHP & MVC
PHP & MVCPHP & MVC
PHP & MVC
Chris Weldon
 

More from Chris Weldon (7)

Keat presentation
Keat presentationKeat presentation
Keat presentation
 
REST Easy - Building RESTful Services in Zend Framework
REST Easy - Building RESTful Services in Zend FrameworkREST Easy - Building RESTful Services in Zend Framework
REST Easy - Building RESTful Services in Zend Framework
 
Beyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver SoftwareBeyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver Software
 
SOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO ProprietySOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO Propriety
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
Unit Testing in SharePoint 2010
Unit Testing in SharePoint 2010Unit Testing in SharePoint 2010
Unit Testing in SharePoint 2010
 
PHP & MVC
PHP & MVCPHP & MVC
PHP & MVC
 

Recently uploaded

Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
ssuserfac0301
 
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
 
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
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
Hiroshi SHIBATA
 
"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota
Fwdays
 
Apps Break Data
Apps Break DataApps Break Data
Apps Break Data
Ivo Velitchkov
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Tosin Akinosho
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
Jason Packer
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
tolgahangng
 
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing InstancesEnergy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Alpen-Adria-Universität
 
Generating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and MilvusGenerating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and Milvus
Zilliz
 
Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)
Jakub Marek
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
akankshawande
 
Leveraging the Graph for Clinical Trials and Standards
Leveraging the Graph for Clinical Trials and StandardsLeveraging the Graph for Clinical Trials and Standards
Leveraging the Graph for Clinical Trials and Standards
Neo4j
 
9 CEO's who hit $100m ARR Share Their Top Growth Tactics Nathan Latka, Founde...
9 CEO's who hit $100m ARR Share Their Top Growth Tactics Nathan Latka, Founde...9 CEO's who hit $100m ARR Share Their Top Growth Tactics Nathan Latka, Founde...
9 CEO's who hit $100m ARR Share Their Top Growth Tactics Nathan Latka, Founde...
saastr
 
Public CyberSecurity Awareness Presentation 2024.pptx
Public CyberSecurity Awareness Presentation 2024.pptxPublic CyberSecurity Awareness Presentation 2024.pptx
Public CyberSecurity Awareness Presentation 2024.pptx
marufrahmanstratejm
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
Brandon Minnick, MBA
 
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-EfficiencyFreshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
ScyllaDB
 
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their MainframeDigital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Precisely
 
What is an RPA CoE? Session 1 – CoE Vision
What is an RPA CoE?  Session 1 – CoE VisionWhat is an RPA CoE?  Session 1 – CoE Vision
What is an RPA CoE? Session 1 – CoE Vision
DianaGray10
 

Recently uploaded (20)

Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
 
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
 
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
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
 
"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota
 
Apps Break Data
Apps Break DataApps Break Data
Apps Break Data
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
 
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing InstancesEnergy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
 
Generating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and MilvusGenerating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and Milvus
 
Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
 
Leveraging the Graph for Clinical Trials and Standards
Leveraging the Graph for Clinical Trials and StandardsLeveraging the Graph for Clinical Trials and Standards
Leveraging the Graph for Clinical Trials and Standards
 
9 CEO's who hit $100m ARR Share Their Top Growth Tactics Nathan Latka, Founde...
9 CEO's who hit $100m ARR Share Their Top Growth Tactics Nathan Latka, Founde...9 CEO's who hit $100m ARR Share Their Top Growth Tactics Nathan Latka, Founde...
9 CEO's who hit $100m ARR Share Their Top Growth Tactics Nathan Latka, Founde...
 
Public CyberSecurity Awareness Presentation 2024.pptx
Public CyberSecurity Awareness Presentation 2024.pptxPublic CyberSecurity Awareness Presentation 2024.pptx
Public CyberSecurity Awareness Presentation 2024.pptx
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
 
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-EfficiencyFreshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
 
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their MainframeDigital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
 
What is an RPA CoE? Session 1 – CoE Vision
What is an RPA CoE?  Session 1 – CoE VisionWhat is an RPA CoE?  Session 1 – CoE Vision
What is an RPA CoE? Session 1 – CoE Vision
 

IoC with PHP

  • 1. IoC with PHP Chris Weldon Dallas TechFest 2011
  • 2. Before We Begin http://bit.ly/rf1pxR git://github.com/neraath/ioc-php-talk.git
  • 3. Your Guide: Chris Weldon • Fightin’ Texas Aggie • .Net and PHP Developer • UNIX and Windows Sysadmin • Senior Consultant at Improving Enterprises • Contact Me: chris@chrisweldon.net
  • 4. Agile, Microsoft, Open Technologies, UX Applied Training, Coaching, Mentoring Certified Consulting Rural Sourcing Recruiting Services
  • 5. Before We Get to IoC... <?php class Authenticator { private $_repository; public function __construct() { $this->_repository = new DataAccessLayer(); } public function authenticate($username, $password) { $hashedPassword = md5($password); $user = $this->_repository->findByUsernameAndPassword( $username, $hashedPassword); return $user === null; } }
  • 6. What are the problems?
  • 7. What are the problems? • Strongly coupled to DataAccessLayer
  • 8. What are the problems? • Strongly coupled to DataAccessLayer Authenticator authenticate() : bool DataAccessLayer findByUsernameAndPassword : array
  • 9. What are the problems? • Strongly coupled to DataAccessLayer • Authenticator Very inflexible authenticate() : bool DataAccessLayer findByUsernameAndPassword : array
  • 10. What are the problems? • Strongly coupled to DataAccessLayer • Authenticator Very inflexible authenticate() : bool • How to configure DataAccessLayer? DataAccessLayer findByUsernameAndPassword : array
  • 11. What are the problems? • Strongly coupled to DataAccessLayer • Authenticator Very inflexible authenticate() : bool • How to configure DataAccessLayer? • DataAccessLayer Let it read configs? findByUsernameAndPassword : array
  • 12. What are the problems? • Strongly coupled to DataAccessLayer • Authenticator Very inflexible authenticate() : bool • How to configure DataAccessLayer? • DataAccessLayer Let it read configs? findByUsernameAndPassword : array • How to test the Authenticator?
  • 13. Let’s solve it • What are our goals? • Decrease coupling • Increase configurability
  • 14. <?php interface IUserRepository { function findByUsernameAndPassword($username, $password); } class DataAccessLayer implements IUserRepository { private $_configParams; private $_database; public function __construct(array $configParams) { $this->_configParams = $configParams; $this->_database = Zend_Db::factory('Pdo_Mysql', $this->_configParams); } public function findByUsernameAndPassword($username, $password) { $query = 'SELECT * FROM users WHERE username = ? AND password = ?'; $result = $this->_database->fetchAll($query, $username, $password); return $result; } }
  • 15. Our Updated Authenticator <?php class Authenticator { private $_repository; public function __construct(IUserRepository $repository) { $this->_repository = $repository; } public function authenticate($username, $password) { $hashedPassword = md5($password); $user = $this->_repository->findByUsernameAndPassword( $username, $hashedPassword); return $user === null; } }
  • 16. Time to Consume <?php class LoginController { public function login($username, $password) { $configuration = Zend_Registry::get('dbconfig'); $dal = new DataAccessLayer($configuration); $authenticator = new Authenticator($dal); if ($authenticator->authenticate($username, $password)) { // Do something to log the user in. } } }
  • 17. Goal Recap • What were our goals? • Decrease coupling • Increase configurability
  • 18. Goal Recap • What were our goals? • Decrease coupling • Increase configurability
  • 19. Goal Recap • What were our goals? • Decrease coupling • Increase configurability
  • 20. What You Saw Was IoC • Inversion of Control changes direction of responsibility • Someone else responsible for creating and providing my dependencies • Most commonly applied pattern: Dependency Injection • Follows Dependency Inversion Principle from SOLID • Culture War: IoC vs. DI vs. Naming vs. Principles vs. Ideology
  • 21. Dependency Inversion • “High-level modules should not depend upon low level modules. They should depend upon abstractions. • “Abstractions should not depend upon details. Details should depend upon abstractions.” Robert Martin
  • 23. Let’s Draw Authenticator authenticate() : bool DataAccessLayer findByUsernameAndPassword : array
  • 24. Let’s Draw Authenticator authenticate() : bool DataAccessLayer findByUsernameAndPassword : array
  • 25. Let’s Draw Authenticator authenticate() : bool Authenticator authenticate() : bool IUserRepository findByUsernameAndPassword : array DataAccessLayer findByUsernameAndPassword : array DataAccessLayer findByUsernameAndPassword : array
  • 26. Benefit: Flexibility <?php class WebServiceUserRepository implements IUserRepository { public function findByUsernameAndPassword($username, $password) { // Fetch our user through JSON or SOAP } } class OAuthRepository implements IUserRepository { public function findByUsernameAndPassword($username, $password) { // Connect to your favorite OAuth provider } }
  • 27. Benefit: Testable <?php class WhenAuthenticating extends PHPUnit_Framework_TestCase { public function testGivenInvalidUsernameAndPasswordShouldReturnFalse() { $stub = $this->getMock('IUserRepository'); $stub->expects($this->any()) ->method('findByUsernameAndPassword') ->will($this->returnValue(null)); $authenticator = new Authenticator($stub); $this->assertFalse($authenticator->authenticate('user', 'pass')); } }
  • 28. Dependency Injection • Now we can inject our dependencies to our consumer classes • Still requires some other class to be tightly coupled to both of those • Need a container that can help abstract the relationship between the interface and implementation
  • 29. <?php class UserRepositoryContainer { /** @return IUserRepository **/ public function getRepository() { $container = new DataAccessLayer(array( 'dsn' => 'mysql://localhost/database', 'username' => 'user', 'password' => 'pass' )); return $container; } } class LoginController { public function login($username, $password) { $container = new UserRepositoryContainer(); $repository = $container->getRepository(); $authenticator = new Authenticator($repository); // ... } }
  • 30. Container Woes • No uniform interface by which to access services • Still tightly coupled with dependencies • Configurability of the container difficult • How to auto-inject dependency for configured consumer classes?
  • 31. Symfony Dependency Injection Container • Two Ways to Setup and Use sfServiceContainer • Create subclass • Manual registration via code or config
  • 32. sfServiceContainer Subclass <?php class UserRepositoryContainer extends sfServiceContainer { protected function getUserRepositoryService() { $container = new DataAccessLayer($this['repository.config']); return $container; } }
  • 33. Consuming the Container <?php class LoginController { public function login($username, $password) { $configuration = Zend_Registry::get('dbconfig'); $container = new UserRepositoryContainer(array( 'repository.config' => $configuration )); $repository = $container->userRepository; $authenticator = new Authenticator($repository); if ($authenticator->authenticate($username, $password)) { // Do something to log the user in. } } }
  • 34. That’s Pretty Nice • Configurability a lot easier • Uniform interface for accessing services • How does this scale when there are lots of dependencies? • Aren’t we still coupling the container to the implementation at compile time?
  • 35. The Builder • Provides a uniform way of describing services, without custom containers • For each service description, we have the flexibility to configure an object: • At instantiation (Constructor Injection) • Post-instantiation (Setter/Method Injection)
  • 36. How to Describe a Service • Code-based or Config-based • Code-based allows for run-time changing of injection parameters • Config-based provides a way to change parameters between environments with no code changes • Not mutually exclusive
  • 37. Code-Based Description <?php // Imagine this is a bootstrap file. $configuration = Zend_Registry::get('dbconfig'); $builder = new sfServiceContainerBuilder(); $builder->register('user_repository', 'DataAccessLayer') ->addArgument($configuration) // OR ->addArgument('%repository.config%') from earlier ->setShared(false); $builder->register('authenticator', 'Authenticator') ->addArgument(new sfServiceReference('user_repository')); Zend_Registry::set('di_container', $builder);
  • 38. Config-Based Description <?xml version="1.0" ?> <container xmlns="http://symfony-project.org/2.0/container"> <parameters> <parameter key="user_repository.dsn">mysql://localhost/database</parameter> <parameter key="user_repository.username">username</parameter> <parameter key="user_repository.password">password</parameter> </parameters> <services> <service id="user_repository" class="DataAccessLayer" shared="false"> <argument type="collection"> <argument key="dsn">%user_repository.dsn%</argument> <argument key="username">%user_repository.username%</argument> <argument key="password">%user_repository.password%</argument> </argument> </service> <service id="authenticator" class="Authenticator"> <argument type="service" id="user_repository" /> </service> </services> </container>
  • 39. Loading the Config <?php // Imagine this is a bootstrap file. $builder = new sfServiceContainerBuilder(); $loader = new sfServiceContainerLoaderFileXml($builder); $loader->load('/pathTo/services.xml'); Zend_Registry::set('di_container', $builder);
  • 40. Using the Container <?php class LoginController { public function login($username, $password) { $container = Zend_Registry::get('di_container'); $authenticator = $container->authenticator; if ($authenticator->authenticate($username, $password)) { // Do something to log the user in. } } }
  • 41. High Level Picture DataAccessLayer findByUsernameAndPassword : array IUserRepository findByUsernameAndPassword : array sfServiceContainerBuilder getService : object setService : void hasService : bool Authenticator authenticate() : bool IAuthenticator authenticate() : bool sfServiceContainerInterface getService : object LoginController setService : void login() : void hasService : bool
  • 42. When to Use a DI Container
  • 43. When to Use a DI Container • Not for model objects (e.g. Orders, Documents, etc.)
  • 44. When to Use a DI Container • Not for model objects (e.g. Orders, Documents, etc.) • Great for resource requirements (e.g. repositories, loggers, etc.)
  • 45. When to Use a DI Container • Not for model objects (e.g. Orders, Documents, etc.) • Great for resource requirements (e.g. repositories, loggers, etc.) • Really great for plugin-type architecture
  • 46. When to Use a DI Container • Not for model objects (e.g. Orders, Documents, etc.) • Great for resource requirements (e.g. repositories, loggers, etc.) • Really great for plugin-type architecture • But not necessary to use Dependency Injection!
  • 48. Other Considerations • Learning curve
  • 49. Other Considerations • Learning curve • Tracking dependencies
  • 50. Other Considerations • Learning curve • Tracking dependencies • Dependency changes
  • 51. Other Considerations • Learning curve • Tracking dependencies • Dependency changes • Setter/method vs. constructor injection
  • 52. Service Lifetimes • setShared() allows you to specify context persistence • If shared, acts like a singleton • Useful if construction is expensive or state persistence required
  • 54. Thank You! http://bit.ly/rf1pxR git://github.com/neraath/ioc-php-talk.git

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n