@ 2018-05-30T18:26:23Z <?php
# basic container
class Container
{
private $raw; // callbacks
private $values; // objects
private $locked;
public function __construct(array $config = [])
{
foreach($config as $id => $callback){
$this->set($id, $callback);
}
}
public function set(string $id, callable $callback): void
{
if(isset($this->locked[$id])){
throw new LockedIdException();
}
$this->raw[$id] = $callback;
}
public function get(string $id)
{
if(!isset($this->raw[$id])){
throw new UnknownIdException();
}
if(isset($this->values[$id])){
return $this->values[$id];
}
$cb = $this->raw[$id];
$val = $this->values[$id] = $cb($this);
$this->locked[$id] = true;
return $val;
}
public function has(string $id): bool
{
return isset($this->values[$id]);
}
}
class Resolver
{
public function __construct(Container $container, WireRule ...$rules)
{
$this->c = $container;
$this->rules = $rules;
}
public function get(string $class)
{
if(!$this->c->has($class)){
$this->c->set($class, $this->resolve($class));
}
return $this->c->get($class);
}
public function resolve(string $class): callable
{
if(!class_exists($class)){
throw new UnknownIdException();
}
if(!method_exists($class, '__construct')){
return function(Container $c) use ($class){ return new $class; };
}
$constructor = new \ReflectionMethod($class, '__construct');
if(count($params = $constructor->getParameters()) === 0){
return function(Container $c) use ($class){ return new $class; };
}
foreach($params as $param){
$args[] = $param->hasType() ? $this->getArgument($param->getType()->__toString()) : null;
}
return function(Container $c) use ($class, $args){
return new $class(...$args);
};
}
public function getArgument(string $type)
{
foreach($this->rules as $rule){
if($rule->match($type)){
$type = $rule->getWiredClass($type);
}
}
return $type ? $this->get($type) : null;
}
}
class Foo { public function __construct(Bar $bar){ $this->bar = $bar; }}
class Bar { public function __construct(Baz $baz){ $this->baz = $baz; }}
class Baz {}
$c = new Resolver(new Container);
var_dump($c->get(Foo::class));
Enable javascript to submit You have javascript disabled. You will not be able to edit any code.
Output for 8.2.0 - 8.2.21 , 8.3.0 - 8.3.9 Deprecated: Creation of dynamic property Resolver::$c is deprecated in /in/orktj on line 52
Deprecated: Creation of dynamic property Resolver::$rules is deprecated in /in/orktj on line 53
Deprecated: Creation of dynamic property Bar::$baz is deprecated in /in/orktj on line 102
Deprecated: Creation of dynamic property Foo::$bar is deprecated in /in/orktj on line 101
object(Foo)#4 (1) {
["bar"]=>
object(Bar)#6 (1) {
["baz"]=>
object(Baz)#8 (0) {
}
}
}
Output for 7.1.0 - 7.1.33 , 7.2.0 - 7.2.33 , 7.3.0 - 7.3.33 , 8.0.0 - 8.0.30 , 8.1.0 - 8.1.29 object(Foo)#4 (1) {
["bar"]=>
object(Bar)#6 (1) {
["baz"]=>
object(Baz)#8 (0) {
}
}
}
Output for 7.4.0 - 7.4.33 Deprecated: Function ReflectionType::__toString() is deprecated in /in/orktj on line 81
Deprecated: Function ReflectionType::__toString() is deprecated in /in/orktj on line 81
object(Foo)#4 (1) {
["bar"]=>
object(Bar)#6 (1) {
["baz"]=>
object(Baz)#8 (0) {
}
}
}
preferences:dark mode live preview
160.53 ms | 403 KiB | 207 Q