Last active
November 28, 2017 17:34
-
-
Save carousel/0200dbbb2dcc4277d74e6b9490f9e68f to your computer and use it in GitHub Desktop.
Most basic IoC/DI container in PHP
This file contains hidden or 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 | |
/* | |
|-------------------------------------------------------------------------- | |
| PHP IoC/DI container | |
|-------------------------------------------------------------------------- | |
| | |
| Most simple IoC/DI container implemented in PHP. | |
| Also includes interface implementation (duck typing is not allowed when binding | |
| concrete class to container) | |
*/ | |
// TEST INTERFACE AND CLASSES | |
interface Vehicle | |
{ | |
public function drive(); | |
} | |
class Car implements Vehicle | |
{ | |
public function drive() | |
{ | |
echo get_class(); | |
} | |
} | |
class Track implements Vehicle | |
{ | |
public function drive() | |
{ | |
echo get_class(); | |
} | |
} | |
//DUCK TYPING WILL THROW EXCEPTION | |
class Train | |
{ | |
public function drive() | |
{ | |
echo get_class(); | |
} | |
} | |
// ACTUAL CONTAINER | |
class Container | |
{ | |
private $bindings = []; | |
public function bind($name, $cb) | |
{ | |
$interface = ucfirst($name); | |
if ($cb() instanceof $interface) { | |
$this->bindings[$name] = $cb; | |
} else { | |
throw new \Exception("Class " . get_class($cb()) . " must implement {$interface} interface"); | |
} | |
} | |
public function make($name) | |
{ | |
foreach ($this->bindings as $key => $val) { | |
if ($key == $name) { | |
return $val(); | |
} else { | |
throw new \Exception("There is no binding for {$key}"); | |
} | |
} | |
} | |
} | |
$container = new Container; | |
$container->bind('vehicle', function () { | |
return new Car; | |
}); | |
class Client | |
{ | |
/** | |
* Implementation injected throw client constructor, but decision is on the framework | |
* to resolve instance and check type | |
*/ | |
public function __construct(Vehicle $vehicle) | |
{ | |
$this->vehicle = $vehicle; | |
} | |
/** | |
* Through container | |
*/ | |
public function getVehicleThroughContainer(Container $container) | |
{ | |
return $container->make('vehicle'); | |
} | |
} | |
//resolve instance from the container | |
$vehicle = $container->make('vehicle'); | |
$client = new Client($vehicle); | |
$client->vehicle->drive(); | |
$client->getVehicleThroughContainer($container)->drive(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment