3v4l.org

run code in 300+ PHP versions simultaneously
<?php class A { } class B { public $a; public function __construct(A $a) { $this->a = $a; } } class C { public $b; public function __construct(B $b) { $this->b = $b; } } class D { public $c; public function __construct(C $c) { $this->c = $c; } } class E { public $d; public function __construct(D $d) { $this->d = $d; } } class F { public $e; public function __construct(E $e) { $this->e = $e; } } class G { public $f; public function __construct(F $f) { $this->f = $f; } } class H { public $g; public function __construct(G $g) { $this->g = $g; } } class I { public $h; public function __construct(H $h) { $this->h = $h; } } class J { public $i; public function __construct(I $i) { $this->i = $i; } } class K { public $j; public function __construct(K $k) { $this->k = $k; } } class Dice { private $rules = []; private $cache = []; private $instances = []; public function addRule($name, Rule $rule) { $this->rules[ltrim($name, '\\')] = $rule; } public function getRule($name) { if (isset($this->rules[ltrim($name, '\\')])) return $this->rules[ltrim($name, '\\')]; foreach ($this->rules as $key => $rule) { if ($rule->instanceOf === null && $key !== '*' && is_subclass_of($name, $key) && $rule->inherit === true) return $rule; } return isset($this->rules['*']) ? $this->rules['*'] : new Rule; } public function create($component, array $args = [], $forceNewInstance = false) { if (!$forceNewInstance && isset($this->instances[$component])) return $this->instances[$component]; if (!isset($this->cache[$component])) { $rule = $this->getRule($component); $class = new \ReflectionClass(empty($rule->instanceOf) ? $component : $rule->instanceOf); $constructor = $class->getConstructor(); $params = $constructor ? $this->getParams($constructor, $rule) : null; $this->cache[$component] = function($args, $forceNewInstance) use ($component, $rule, $class, $constructor, $params) { if ($rule->shared) { if ($constructor) { try { $this->instances[$component] = $object = $class->newInstanceWithoutConstructor(); $constructor->invokeArgs($object, $params($args)); } catch (\ReflectionException $r) { $this->instances[$component] = $object = $class->newInstanceArgs($params($args)); } } else { $this->instances[$component] = $object = $class->newInstanceWithoutConstructor(); } } else $object = $params ? $class->newInstanceArgs($params($args)) : new $class->name; if (!empty($rule->call)) foreach ($rule->call as $call) $class->getMethod($call[0])->invokeArgs($object, call_user_func($this->getParams($class->getMethod($this->expand($call[0])), new Rule), $call[1])); return $object; }; } return $this->cache[$component]($args, $forceNewInstance); } private function expand($param, array $share = []) { if (is_array($param)) return array_map(function($p) use($share) { return $this->expand($p, $share); }, $param); if ($param instanceof Instance) return $this->create($param->name, $share); else if (is_callable($param)) return $param($this); return $param; } private function getParams(\ReflectionMethod $method, Rule $rule) { $subs = empty($rule->substitutions) ? null :$rule->substitutions; $paramClasses = []; foreach ($method->getParameters() as $param) $paramClasses[] = $param->getClass() ? $param->getClass()->name : null; return function($args) use ($paramClasses, $rule, $subs) { $share = empty($rule->shareInstances) ? [] : array_map([$this, 'create'], $rule->shareInstances); if (!empty($share) || !empty($rule->constructParams)) $args = array_merge($args, $this->expand($rule->constructParams, $share), $share); $parameters = []; foreach ($paramClasses as $class) { if (!empty($args)) for ($i = 0; $i < count($args); $i++) { if ($class && $args[$i] instanceof $class) { $parameters[] = array_splice($args, $i, 1)[0]; continue 2; } } if (!empty($subs) && isset($subs[$class])) $parameters[] = is_string($subs[$class]) ? $this->create($subs[$class]) : $this->expand($subs[$class]); else if (!empty($class)) $parameters[] = $this->create($class, $share, !empty($rule->newInstances) && in_array(strtolower($class), array_map('strtolower', $rule->newInstances))); else if (!empty($args)) $parameters[] = array_shift($args); } return $parameters; }; } } class Rule { public $shared = false; public $constructParams = []; public $substitutions = []; public $newInstances = []; public $instanceOf; public $call = []; public $inherit = true; public $shareInstances = []; } class Instance { public $name; public function __construct($instance) { $this->name = $instance; } } class Dice2 { private $rules = []; private $cache = []; private $instances = []; public function addRule($name, Rule $rule) { $this->rules[ltrim($name, '\\')] = $rule; } public function getRule($name) { if (isset($this->rules[ltrim($name, '\\')])) return $this->rules[ltrim($name, '\\')]; foreach ($this->rules as $key => $rule) { if ($rule->instanceOf === null && $key !== '*' && is_subclass_of($name, $key) && $rule->inherit === true) return $rule; } return isset($this->rules['*']) ? $this->rules['*'] : new Rule; } public function create($component, array $args = [], $forceNewInstance = false) { if (!$forceNewInstance && isset($this->instances[$component])) return $this->instances[$component]; if (!isset($this->cache[$component])) { $rule = $this->getRule($component); $class = new \ReflectionClass(empty($rule->instanceOf) ? $component : $rule->instanceOf); $constructor = $class->getConstructor(); $params = $constructor ? $this->getParams($constructor, $rule) : null; $this->cache[$component] = function($args, $forceNewInstance) use ($component, $rule, $class, $constructor, $params) { if ($rule->shared) { $this->instances[$component] = $object = $class->isInternal() && $constructor ? $class->newInstanceArgs($params($args)) : $class->newInstanceWithoutConstructor(); if ($constructor && !$class->isInternal()) $constructor->invokeArgs($object, $params($args)); } else $object = $params ? new $class->name(...$params($args)) : new $class->name; if (!empty($rule->call)) foreach ($rule->call as $call) $class->getMethod($call[0])->invokeArgs($object, call_user_func($this->getParams($class->getMethod($this->expand($call[0])), new Rule), $call[1])); return $object; }; } return $this->cache[$component]($args, $forceNewInstance); } private function expand($param, array $share = []) { if (is_array($param)) return array_map(function($p) use($share) { return $this->expand($p, $share); }, $param); if ($param instanceof Instance) return $this->create($param->name, $share); else if (is_callable($param)) return $param($this); return $param; } private function getParams(\ReflectionMethod $method, Rule $rule) { $subs = empty($rule->substitutions) ? null :$rule->substitutions; $paramClasses = []; foreach ($method->getParameters() as $param) $paramClasses[] = $param->getClass() ? $param->getClass()->name : null; return function($args) use ($paramClasses, $rule, $subs) { $share = empty($rule->shareInstances) ? [] : array_map([$this, 'create'], $rule->shareInstances); if (!empty($share) || !empty($rule->constructParams)) $args = array_merge($args, $this->expand($rule->constructParams, $share), $share); $parameters = []; foreach ($paramClasses as $class) { if (!empty($args)) for ($i = 0; $i < count($args); $i++) { if ($class && $args[$i] instanceof $class) { $parameters[] = array_splice($args, $i, 1)[0]; continue 2; } } if (!empty($subs) && isset($subs[$class])) $parameters[] = is_string($subs[$class]) ? $this->create($subs[$class]) : $this->expand($subs[$class]); else if (!empty($class)) $parameters[] = $this->create($class, $share, !empty($rule->newInstances) && in_array(strtolower($class), array_map('strtolower', $rule->newInstances))); else if (!empty($args)) $parameters[] = array_shift($args); } return $parameters; }; } } $dice1 = new Dice; $dice2 = new Dice2; $j1 = $dice1->create('J'); $j2 = $dice2->create('J'); $t1 = microtime(true); for ($i = 0; $i < 10000; $i++) { $j = $dice1->create('J'); } $t2 = microtime(true); echo 'dice1: ' . ($t2 - $t1) . "\n\n"; $t1 = microtime(true); for ($i = 0; $i < 10000; $i++) { $j = $dice2->create('J'); } $t2 = microtime(true); echo 'dice1: ' . ($t2 - $t1) . "\n\n";
Output for 7.4.0
dice1: 0.10630488395691 dice1: 0.10661721229553
Output for 7.3.12
dice1: 0.14965200424194 dice1: 0.13864493370056
Output for 7.3.11
dice1: 0.11842799186707 dice1: 0.10567712783813
Output for 7.3.10
dice1: 0.10418486595154 dice1: 0.10264301300049
Output for 7.3.9
dice1: 0.13548111915588 dice1: 0.09322714805603
Output for 7.3.8
dice1: 0.096839189529419 dice1: 0.10510301589966
Output for 7.3.7
dice1: 0.089824914932251 dice1: 0.098773956298828
Output for 7.3.6
dice1: 0.11837983131409 dice1: 0.13049793243408
Output for 7.3.5
dice1: 0.10363411903381 dice1: 0.091729879379272
Output for 7.3.4
dice1: 0.091386795043945 dice1: 0.091121196746826
Output for 7.3.3
dice1: 0.10534501075745 dice1: 0.098872184753418
Output for 7.3.2
dice1: 0.096735000610352 dice1: 0.1175971031189
Output for 7.3.1
dice1: 0.099518060684204 dice1: 0.098044872283936
Output for 7.3.0
dice1: 0.12313079833984 dice1: 0.10568785667419
Output for 7.2.25
dice1: 0.18495893478394 dice1: 0.14590096473694
Output for 7.2.24
dice1: 0.13322615623474 dice1: 0.11851811408997
Output for 7.2.23
dice1: 0.11774301528931 dice1: 0.12574887275696
Output for 7.2.22
dice1: 0.13632702827454 dice1: 0.11550378799438
Output for 7.2.21
dice1: 0.13289308547974 dice1: 0.11219477653503
Output for 7.2.20
dice1: 0.1131739616394 dice1: 0.11200213432312
Output for 7.2.19
dice1: 0.11444616317749 dice1: 0.11965203285217
Output for 7.2.18
dice1: 0.13879203796387 dice1: 0.11075806617737
Output for 7.2.17
dice1: 0.12527704238892 dice1: 0.15454888343811
Output for 7.2.0
dice1: 0.064551115036011 dice1: 0.060163021087646
Output for 7.1.33
dice1: 0.15738916397095 dice1: 0.1514778137207
Output for 7.1.32
dice1: 0.16988587379456 dice1: 0.16224312782288
Output for 7.1.31
dice1: 0.20651006698608 dice1: 0.1558690071106
Output for 7.1.30
dice1: 0.21288418769836 dice1: 0.16103601455688
Output for 7.1.29
dice1: 0.14858412742615 dice1: 0.14405989646912
Output for 7.1.28
dice1: 0.14898610115051 dice1: 0.14545917510986
Output for 7.1.27
dice1: 0.18032503128052 dice1: 0.1451210975647
Output for 7.1.26
dice1: 0.15536499023438 dice1: 0.14334106445312
Output for 7.1.7
dice1: 0.084866046905518 dice1: 0.063967943191528
Output for 7.1.6
dice1: 0.10573196411133 dice1: 0.071253061294556
Output for 7.1.5
dice1: 0.11230897903442 dice1: 0.073814868927002
Output for 7.1.0
dice1: 0.12423610687256 dice1: 0.090756177902222
Output for 7.0.20
dice1: 0.084161996841431 dice1: 0.071856021881104
Output for 7.0.14
dice1: 0.13094687461853 dice1: 0.092476844787598
Output for 7.0.12
dice1: 0.13531708717346 dice1: 0.09647011756897
Output for 7.0.11
dice1: 0.13359093666077 dice1: 0.094380140304565
Output for 7.0.10
dice1: 0.12842607498169 dice1: 0.095478057861328
Output for 7.0.9
dice1: 0.12905192375183 dice1: 0.093661069869995
Output for 7.0.8
dice1: 0.13105893135071 dice1: -0.32270884513855
Output for 7.0.7
dice1: 0.1290340423584 dice1: 0.092841863632202
Output for 7.0.6
dice1: 0.13251709938049 dice1: 0.094222068786621
Output for 7.0.5
dice1: 0.13619804382324 dice1: 0.096045017242432
Output for 7.0.4
dice1: 0.13443398475647 dice1: 0.09463095664978
Output for 7.0.3
dice1: 0.13024592399597 dice1: 0.094304084777832
Output for 7.0.2
dice1: 0.12329816818237 dice1: 0.087915897369385
Output for 7.0.1
dice1: 0.1336190700531 dice1: 0.094938039779663
Output for 7.0.0
dice1: 0.13061189651489 dice1: 0.090490102767944
Output for 5.6.28
dice1: 0.26062178611755 dice1: -0.14304184913635
Output for 5.6.26
dice1: 0.24897503852844 dice1: 0.18410587310791
Output for 5.6.25
dice1: 0.1046290397644 dice1: 0.18799090385437
Output for 5.6.24
dice1: -0.17196893692017 dice1: 0.18747711181641
Output for 5.6.23
dice1: 0.2396411895752 dice1: 0.18644285202026
Output for 5.6.22
dice1: -0.0076589584350586 dice1: 0.18979811668396
Output for 5.6.21
dice1: 0.22951912879944 dice1: 0.18392109870911
Output for 5.6.20
dice1: 0.24075293540955 dice1: 0.17688918113708
Output for 5.6.19
dice1: 0.21180200576782 dice1: 0.18238687515259
Output for 5.6.18
dice1: 0.24832487106323 dice1: 0.18479514122009
Output for 5.6.17
dice1: 0.24313902854919 dice1: 0.18330597877502
Output for 5.6.16
dice1: 0.01963996887207 dice1: 0.18193483352661
Output for 5.6.15
dice1: 0.24191999435425 dice1: 0.18578004837036
Output for 5.6.14
dice1: 0.23551607131958 dice1: 0.17615509033203
Output for 5.6.13
dice1: 0.24272704124451 dice1: 0.18653321266174
Output for 5.6.12
dice1: 0.00023794174194336 dice1: 0.18666696548462
Output for 5.6.11
dice1: 0.24220204353333 dice1: -0.65352082252502
Output for 5.6.10
dice1: 0.24377989768982 dice1: 0.18662810325623
Output for 5.6.9
dice1: 0.24490118026733 dice1: 0.18643689155579
Output for 5.6.8
dice1: 0.24054789543152 dice1: 0.18914699554443
Output for 5.6.7
dice1: 0.054921865463257 dice1: 0.17948293685913
Output for 5.6.6
dice1: 0.24124503135681 dice1: -0.65244889259338
Output for 5.6.5
dice1: 0.23896503448486 dice1: 0.18144798278809
Output for 5.6.4
dice1: 0.24649810791016 dice1: 0.18099403381348
Output for 5.6.3
dice1: 0.14708805084229 dice1: 0.18333005905151
Output for 5.6.2
dice1: 0.23519492149353 dice1: -0.35163497924805
Output for 5.6.1
dice1: 0.24672508239746 dice1: 0.18249201774597
Output for 5.6.0
dice1: 0.21862506866455 dice1: 0.18244504928589
Output for 5.5.0 - 5.5.38
Parse error: syntax error, unexpected '.' in /in/BlXCT on line 222
Process exited with code 255.
Output for 5.4.0 - 5.4.45
Parse error: syntax error, unexpected '.', expecting ')' in /in/BlXCT on line 222
Process exited with code 255.

preferences:
136.43 ms | 401 KiB | 167 Q