Slide 1

Slide 1 text

Dependency Injection Reinventing how you manage PHP classes

Slide 2

Slide 2 text

DI? What is DI?

Slide 3

Slide 3 text

Dependency Injection means giving an object its instance variables. Really. That's it. - James Shore The Really Short Version

Slide 4

Slide 4 text

Why This Kolaveri DI?

Slide 5

Slide 5 text

Why This Kolaveri DI? CHANGE

Slide 6

Slide 6 text

Why DI? • Maintainable • Extendible • Flexible • Configurable • Testable • Reusable • Interoperable

Slide 7

Slide 7 text

A Real Life Example

Slide 8

Slide 8 text

“Dependency Injection” is a 25-dollar term for a 5-cent concept. Don’t Panic!

Slide 9

Slide 9 text

A PHP Example

Slide 10

Slide 10 text

class MySqlDB { private $_link; public function __construct($host, $username, $password, $database) { $this->_link = mysql_connect($host, $username, $password); mysql_select_db($database); } public function insert($data, $table) { array_map('mysql_real_escape_string', $data); $query = 'INSERT INTO `' . $table . '` (`' . implode('`,`', array_keys($data)) . '`)' . 'VALUES ("' . implode('","', $data) . '" )'; return mysql_query($query, $this->_link); } // ... }

Slide 11

Slide 11 text

define('MYSQL_HOST', 'localhost'); define('MYSQL_USER', 'root'); define('MYSQL_PASS', ''); define('MYSQL_DB', 'test'); class User { private $_db; private $_info = array(); public function __construct() { $this->_db = new MySqlDB(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB); } public function register($name, $email, $age, $sex) { $this->_info = compact('name', 'email', 'age', 'sex'); $this->_db->insert($this->_info, 'users'); } // ... } $user = new User(); $user->register('Tasneem', '[email protected]', 18, 'female');

Slide 12

Slide 12 text

// You can hardcode it public function __construct() { $this->_db = new MySqlDB('localhost', 'root', '', 'test'); } // You can configure it with an array public function __construct($config) { $this->_db = new MySqlDB($config['host'], $config['user'], $config['pass'], $config['db']); } // And, What we saw earlier public function __construct() { $this->_db = new MySqlDB(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB); } Options

Slide 13

Slide 13 text

What if I want to use a different database like MongoDB or SQLite

Slide 14

Slide 14 text

Hey wait, I can improve it!

Slide 15

Slide 15 text

class User { protected $_db; protected $_info = array(); public function __construct() { $registry = RegistrySingleton::getInstance(); $this->_db = $registry->database; } public function register($name, $email, $age, $sex) { $this->_info = compact('name', 'email', 'age', 'sex'); $this->_db->insert($this->info, 'users'); } // ... } $user = new User(); $user->register('Tasneem', '[email protected]', 18, 'female');

Slide 16

Slide 16 text

Smart Huh???

Slide 17

Slide 17 text

So, now User depends on Registry

Slide 18

Slide 18 text

Let’s do it with DI

Slide 19

Slide 19 text

class User { protected $_db; protected $_info = array(); public function __construct($database) { $this->_db = $database; } public function register($name, $email, $age, $sex) { $this->_info = compact('name', 'email', 'age', 'sex'); $this->_db->insert($this->_info, 'users'); } // ... } $mysql = new MySqlDB('localhost', 'root', '', 'test'); $user = new User($mysql); $user->register('Tasneem', '[email protected]', 18, 'female');

Slide 20

Slide 20 text

But there are still rooms for improvement

Slide 21

Slide 21 text

Interface

Slide 22

Slide 22 text

Ever heard of Type Hinting

Slide 23

Slide 23 text

public function test(OtherClass $otherClass) { } public function testInterface(Interface $interface) { } public function testArray(array $inputArray) { } Type Hinting Since PHP 5.1

Slide 24

Slide 24 text

interface Database { public function insert(array $data, $table); } class User { protected $_db; protected $_info = array(); public function __construct(Database $database) { $this->_db = $database; } public function register($name, $email, $age, $sex) { $this->_info = compact('name', 'email', 'age', 'sex'); $this->_db->insert($this->_info, 'users'); } // ... } $mysql = new MySqlDB('localhost', 'root', '', 'test'); $user = new User($mysql); $user->register('Tasneem', '[email protected]', 18, 'female');

Slide 25

Slide 25 text

class MySqlDB implements Database { protected $_link; public function __construct($host, $username, $password, $database) { $this->_link = mysql_connect($host, $username, $password); mysql_select_db($database); } public function insert(array $data, $table) { array_map('mysql_real_escape_string', $data); $query = 'INSERT INTO `' . $table . '` (`' . implode('`,`', array_keys($data)) . '`)' . 'VALUES ("' . implode('","', $data) . '" )'; return mysql_query($query, $this->_link); } // ... } MySQL

Slide 26

Slide 26 text

class MongoDB implements Database { // ... public function insert(array $data, $table) { // Save the passed array using MongoDB } // ... } $mongoDb = new MongoDB('localhost', 'root', '', 'test'); $user = new User($mongoDb); $user->register('Tasneem', '[email protected]', 18, 'female'); MongoDB

Slide 27

Slide 27 text

class SQLiteDB implements Database { // ... public function insert(array $data, $table) { // Save the passed array using SQLite } // ... } $sqlite = new SQLiteDB('app.db', 'test'); $user = new User($sqlite); $user->register('Tasneem', '[email protected]', 18, 'female'); SQLite

Slide 28

Slide 28 text

class TestDB implements Database { protected $_data = array(); public function insert(array $data, $table) { $this->_data[$table] = $data; } public function get($table) { return $this->_data[$table]; } } $fakeDb = new TestDB(); $user = new User($fakeDb); $user->register('Tasneem', '[email protected]', 18, 'female'); print_r($fakeDb->get('users')); TestDB

Slide 29

Slide 29 text

DI Container

Slide 30

Slide 30 text

class Container { protected $s=array(); function __set($k, $c) { $this->s[$k]=$c; } function __get($k) { return $this->s[$k]($this); } } Twittee A DI Container in a Tweet using the power of PHP 5.3

Slide 31

Slide 31 text

$c = new Container(); $c->mysql = function ($c) { return new MySqlDB('localhost', 'root', '', 'test'); } $c->user = function ($c) { $db = $c->mysql; return new User($db); } // When you need a user $user = $c->user; // Instead of $user = new User(); Container

Slide 32

Slide 32 text

http://components.symfony-project.org/dependency-injection/ http://pimple.sensiolabs.org/ http://twittee.org/ More...

Slide 33

Slide 33 text

Question?

Slide 34

Slide 34 text

@rifat [email protected] http://VistaArc.com/ http://OmicronLab.com/ Thank You