Skip to content

Instantly share code, notes, and snippets.

@ivalkenburg
Last active April 30, 2017 16:05
Show Gist options
  • Save ivalkenburg/608aff6fb2ff86a9766f998b3dcd7ea9 to your computer and use it in GitHub Desktop.
Save ivalkenburg/608aff6fb2ff86a9766f998b3dcd7ea9 to your computer and use it in GitHub Desktop.
<?php
class Resolver {
protected $container;
public function __construct($container)
{
$this->container = $container;
}
public function resolveClass($class, $arguments = [])
{
$reflector = new ReflectionClass($class);
// Kijken of we $class kunnen instanteeren, zo niet dan gooien we een exception.
if ( ! $reflector->isInstantiable())
{
throw new Exception("Class [$class] is not instantiable");
}
// We halen ReflectionMethod op van de constructor, zo niet dan krijgen we null value
// en returnen we gewoon een nieuw object.
if (is_null($constructor = $reflector->getConstructor()))
{
return new $class;
}
// We vragen een array van alle parameters in de constructor op.
$parameters = $constructor->getParameters();
// lege array maken die onze opgeloste eisen bewaren.
$dependencies = [];
// we loopen over parameters array heen om ze optelossen.
foreach ($parameters as $parameter) {
// eerst kijken we of de paramater voorkomt in de argumenten lijst die we mee hebben gegeven.
if (isset($arguments[$parameter->name]))
{
$dependencies[] = $arguments[$parameter->name];
}
// zo niet dan kijken we of we het hebben over een typed hinted class.
elseif ($dependency = $parameter->getClass())
{
// zo ja dan kijken we of de class voorkomt in de service container.
if (isset($this->container[$dependency->name]))
{
$dependencies[] = $this->container[$dependency->name];
}
// zo niet dan gaan we een recursive resolve uitvoeren en gaan we het zelfde doen wat we hier doen.
else
{
$dependencies[] = $this->resolveClass($dependency->name);
}
}
// als alles niet mogelijk is proberen we de default value te gebruiken.
elseif ($default = $parameter->getDefaultValue())
{
$dependencies[] = $default;
}
}
// als laatste maken we een nieuw object met de opgeloste parameters.
return $reflector->newInstanceArgs($dependencies);
}
}
class Foo {
public function __construct(Bar $bar, Something $something, $id, $name)
{
$this->bar = $bar;
$this->something = $something;
$this->id = $id;
$this->name = $name;
}
public function test()
{
return $this->something->getTest();
}
}
class Bar {
}
class Something {
protected $test;
public function __construct($test)
{
$this->test = $test;
}
public function getTest()
{
return $this->test;
}
}
$container[Something::class] = new Something('test0r');
$arguments = [
'id' => 1,
'name' => 'Igor'
];
$foo = (new Resolver($container))->resolveClass(Foo::class, $arguments);
echo $foo->test();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment