-
-
Save xeoncross/2990773 to your computer and use it in GitHub Desktop.
PHP 5.3 Lightweight IOC container
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require_once 'ioc.php'; | |
class Material { | |
private $materialName = null; | |
public function __construct() { | |
} | |
public function setMaterialName($name) { | |
$this->materialName = $name; | |
} | |
public function getMaterialName() { | |
return $this->materialName; | |
} | |
} | |
class Wood extends Material { | |
public function __construct() { | |
parent::__construct(); | |
$this->setMaterialName("wood"); | |
} | |
} | |
class Steel extends Material { | |
public function __construct() { | |
parent::__construct(); | |
$this->setMaterialName("steel"); | |
} | |
} | |
class WoodWindow { | |
private $material; | |
public function __construct(Wood $material) { | |
$this->material = $material; | |
} | |
public function getWindowMaterial() { | |
return $this->material->getMaterialName(); | |
} | |
} | |
class SteelDoor { | |
private $material; | |
private $strength = 5; | |
public function __construct(Steel $material) { | |
$this->material = $material; | |
} | |
public function getDoorMaterial() { | |
return $this->material->getMaterialName(); | |
} | |
public function setStrength($strength) { | |
$this->strength = $strength; | |
} | |
} | |
class ReinforcedSteelDoor extends SteelDoor { | |
public function __construct(Steel $material) { | |
parent::__construct($material); | |
$this->setStrength(10); | |
} | |
} | |
class House { | |
private $door; | |
private $window; | |
public function __construct(SteelDoor $door, WoodWindow $window) { | |
$this->door = $door; | |
$this->window = $window; | |
} | |
public function describe() { | |
var_dump($this->door); | |
var_dump($this->window); | |
} | |
} | |
$ioc = new IOC(); | |
$house = $ioc->make("House"); | |
$house->describe(); | |
// how about a better door | |
// just override the used class for the steel door | |
$ioc->forClass("SteelDoor", "ReinforcedSteelDoor"); | |
$house = $ioc->make("House"); | |
$house->describe(); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* Lightweight IOC container | |
*/ | |
class IOC { | |
// if a hinted class name is matched here | |
// use the associated value as the new class | |
private $constraints = array(); | |
public function forClass($originalHinted, $newClass) { | |
if (!array_key_exists($originalHinted, $this->constraints)) { | |
$this->constraints[$originalHinted] = $newClass; | |
} | |
} | |
public function make($object) { | |
// parameters for the construct of object | |
$objectParameters = array(); | |
// all the arguments passed to make | |
// can be of any type | |
$args = func_get_args(); | |
// skip the object name for the other types of parameters | |
array_shift($args); | |
if (is_string($object) && class_exists($object)) { | |
// defining class for the object we try to make | |
$ref = new ReflectionClass($object); | |
// object constructor | |
$constructor = $ref->getConstructor(); | |
if ($constructor) { | |
// constructor parameters | |
$constructorParameters = $constructor->getParameters(); | |
$otherTypeParameterCounter = 0; // incremented only when the type of the arg is not a class | |
foreach ($constructorParameters as $parameter) { | |
// the parameter should be an instance of the hinted class | |
$hintedClass = $parameter->getClass(); | |
if ($hintedClass != NULL) { | |
$hintedClassName = $hintedClass->getName(); | |
// overridden hinted class | |
if (array_key_exists($hintedClassName, $this->constraints)) { | |
$hintedClassName = $this->constraints[$hintedClassName]; | |
} | |
// instantiate the class and add it to the | |
// parameters list | |
if (class_exists($hintedClassName)) { | |
// the hinted class could have hinted class parameters and other types as well | |
$objectParameters[] = $this->make($hintedClassName); | |
} | |
} else { | |
// other type of parameter | |
// found in the args array | |
// these parameters are passed to the make function after | |
// the object to create | |
$objectParameters[] = $args[$otherTypeParameterCounter]; | |
$otherTypeParameterCounter++; | |
} | |
} | |
} | |
if (empty($objectParameters)) { | |
return new $object; | |
} else { | |
return $ref->newInstanceArgs($objectParameters); | |
} | |
} else { | |
die("Invalid use of IOC, $object is not a class."); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object(SteelDoor)[12] | |
private 'material' => | |
object(Steel)[13] | |
private 'materialName' (Material) => string 'steel' (length=5) | |
private 'strength' => int 5 | |
object(WoodWindow)[14] | |
private 'material' => | |
object(Wood)[15] | |
private 'materialName' (Material) => string 'wood' (length=4) | |
object(ReinforcedSteelDoor)[17] | |
private 'material' (SteelDoor) => | |
object(Steel)[18] | |
private 'materialName' (Material) => string 'steel' (length=5) | |
private 'strength' (SteelDoor) => int 10 | |
object(WoodWindow)[19] | |
private 'material' => | |
object(Wood)[20] | |
private 'materialName' (Material) => string 'wood' (length=4) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment