Skip to content

Instantly share code, notes, and snippets.

@carousel
Last active November 28, 2017 17:34
Show Gist options
  • Save carousel/0200dbbb2dcc4277d74e6b9490f9e68f to your computer and use it in GitHub Desktop.
Save carousel/0200dbbb2dcc4277d74e6b9490f9e68f to your computer and use it in GitHub Desktop.
Most basic IoC/DI container in PHP
<?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