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.1
dice1: 0.14901208877563 dice1: 0.14474987983704
Output for 7.4.0
dice1: 0.14813804626465 dice1: 0.1424081325531
Output for 7.3.13
dice1: 0.14942097663879 dice1: 0.1421799659729
Output for 7.3.12
dice1: 0.12298011779785 dice1: 0.10758805274963
Output for 7.3.11
dice1: 0.14893388748169 dice1: 0.14411115646362
Output for 7.3.10
dice1: 0.1028459072113 dice1: 0.13903403282166
Output for 7.3.9
dice1: 0.14460396766663 dice1: 0.10287714004517
Output for 7.3.8
dice1: 0.14552593231201 dice1: 0.09244179725647
Output for 7.3.7
dice1: 0.10277700424194 dice1: 0.10088682174683
Output for 7.3.6
dice1: 0.14460802078247 dice1: 0.12889790534973
Output for 7.3.5
dice1: 0.14297008514404 dice1: 0.093142986297607
Output for 7.3.4
dice1: 0.13678908348083 dice1: 0.090444087982178
Output for 7.3.3
dice1: 0.14240503311157 dice1: 0.13777899742126
Output for 7.3.2
dice1: 0.10859513282776 dice1: 0.10477089881897
Output for 7.3.1
dice1: 0.10849404335022 dice1: 0.1120297908783
Output for 7.3.0
dice1: 0.12002515792847 dice1: 0.092039108276367
Output for 7.2.26
dice1: 0.14404797554016 dice1: 0.13311409950256
Output for 7.2.25
dice1: 0.11326694488525 dice1: 0.12805700302124
Output for 7.2.24
dice1: 0.11017489433289 dice1: 0.12781000137329
Output for 7.2.23
dice1: 0.12295079231262 dice1: 0.11997389793396
Output for 7.2.22
dice1: 0.12405395507812 dice1: 0.16384100914001
Output for 7.2.21
dice1: 0.10653519630432 dice1: 0.10550093650818
Output for 7.2.20
dice1: 0.14463591575623 dice1: 0.16614079475403
Output for 7.2.19
dice1: 0.1709611415863 dice1: 0.12185311317444
Output for 7.2.18
dice1: 0.16423916816711 dice1: 0.10494089126587
Output for 7.2.17
dice1: 0.14265489578247 dice1: 0.12848711013794
Output for 7.2.16
dice1: 0.16900587081909 dice1: 0.15860295295715
Output for 7.2.15
dice1: 0.11205983161926 dice1: 0.13224101066589
Output for 7.2.14
dice1: 0.11585187911987 dice1: 0.10194206237793
Output for 7.2.13
dice1: 0.15064191818237 dice1: 0.15360307693481
Output for 7.2.12
dice1: 0.16813898086548 dice1: 0.11358690261841
Output for 7.2.11
dice1: 0.16740107536316 dice1: 0.10222983360291
Output for 7.2.10
dice1: 0.15469908714294 dice1: 0.10982894897461
Output for 7.2.9
dice1: 0.10611796379089 dice1: 0.1550920009613
Output for 7.2.8
dice1: 0.14972805976868 dice1: 0.13128304481506
Output for 7.2.7
dice1: 0.10793900489807 dice1: 0.10758709907532
Output for 7.2.6
dice1: 0.1665780544281 dice1: 0.11295294761658
Output for 7.2.5
dice1: 0.11803197860718 dice1: 0.10607409477234
Output for 7.2.4
dice1: 0.16525292396545 dice1: 0.16846680641174
Output for 7.2.3
dice1: 0.10892796516418 dice1: 0.10565781593323
Output for 7.2.2
dice1: 0.16488814353943 dice1: 0.1399610042572
Output for 7.2.1
dice1: 0.10672187805176 dice1: 0.13959097862244
Output for 7.2.0
dice1: 0.17088794708252 dice1: 0.16866993904114
Output for 7.1.33
dice1: 0.16801714897156 dice1: 0.20989084243774
Output for 7.1.32
dice1: 0.21554088592529 dice1: 0.16074395179749
Output for 7.1.31
dice1: 0.14780282974243 dice1: 0.19040107727051
Output for 7.1.30
dice1: 0.17364001274109 dice1: 0.18028402328491
Output for 7.1.29
dice1: 0.14344310760498 dice1: 0.15515804290771
Output for 7.1.28
dice1: 0.16551899909973 dice1: 0.16061997413635
Output for 7.1.27
dice1: 0.16950702667236 dice1: 0.13926887512207
Output for 7.1.26
dice1: 0.14837408065796 dice1: 0.1813690662384
Output for 7.1.25
dice1: 0.20911693572998 dice1: 0.16399097442627
Output for 7.1.24
dice1: 0.18669581413269 dice1: 0.13870310783386
Output for 7.1.23
dice1: 0.1847779750824 dice1: 0.19986987113953
Output for 7.1.22
dice1: 0.16169285774231 dice1: 0.18579697608948
Output for 7.1.21
dice1: 0.14557504653931 dice1: 0.15554022789001
Output for 7.1.20
dice1: 0.18097186088562 dice1: 0.14040303230286
Output for 7.1.19
dice1: 0.16998791694641 dice1: 0.14438986778259
Output for 7.1.18
dice1: 0.14191293716431 dice1: 0.16012406349182
Output for 7.1.17
dice1: 0.13809299468994 dice1: 0.19762706756592
Output for 7.1.16
dice1: 0.21733999252319 dice1: 0.18911194801331
Output for 7.1.15
dice1: 0.19319987297058 dice1: 0.14414215087891
Output for 7.1.14
dice1: 0.21317505836487 dice1: 0.17140889167786
Output for 7.1.13
dice1: 0.16962790489197 dice1: 0.15972208976746
Output for 7.1.12
dice1: 0.1454918384552 dice1: 0.20571684837341
Output for 7.1.11
dice1: 0.21270203590393 dice1: 0.1429648399353
Output for 7.1.10
dice1: 0.21347689628601 dice1: 0.20923805236816
Output for 7.1.9
dice1: 0.15970206260681 dice1: 0.15488886833191
Output for 7.1.8
dice1: 0.19868302345276 dice1: 0.13879704475403
Output for 7.1.7
dice1: 0.18201494216919 dice1: 0.16499900817871
Output for 7.1.6
dice1: 0.15889692306519 dice1: 0.13775396347046
Output for 7.1.5
dice1: 0.21712303161621 dice1: 0.19636917114258
Output for 7.1.4
dice1: 0.18987798690796 dice1: 0.21028304100037
Output for 7.1.3
dice1: 0.18379688262939 dice1: 0.17151308059692
Output for 7.1.2
dice1: 0.14164090156555 dice1: 0.13622403144836
Output for 7.1.1
dice1: 0.15716314315796 dice1: 0.15440320968628
Output for 7.1.0
dice1: 0.14423513412476 dice1: 0.14215683937073
Output for 7.0.33
dice1: 0.16901516914368 dice1: 0.18093109130859
Output for 7.0.32
dice1: 0.15631484985352 dice1: 0.16337299346924
Output for 7.0.31
dice1: 0.15565395355225 dice1: 0.22580289840698
Output for 7.0.30
dice1: 0.24928498268127 dice1: 0.2122061252594
Output for 7.0.29
dice1: 0.21968698501587 dice1: 0.20525598526001
Output for 7.0.28
dice1: 0.18115997314453 dice1: 0.24312806129456
Output for 7.0.27
dice1: 0.18893790245056 dice1: 0.15778398513794
Output for 7.0.26
dice1: 0.16129112243652 dice1: 0.18972206115723
Output for 7.0.25
dice1: 0.16509103775024 dice1: 0.15994191169739
Output for 7.0.24
dice1: 0.19881105422974 dice1: 0.15405797958374
Output for 7.0.23
dice1: 0.16935396194458 dice1: 0.15213012695312
Output for 7.0.22
dice1: 0.15889883041382 dice1: 0.15382790565491
Output for 7.0.21
dice1: 0.16506910324097 dice1: 0.19299101829529
Output for 7.0.20
dice1: 0.22072386741638 dice1: 0.23681688308716
Output for 7.0.19
dice1: 0.22461605072021 dice1: 0.1952428817749
Output for 7.0.18
dice1: 0.18114805221558 dice1: 0.17219710350037
Output for 7.0.17
dice1: 0.23966717720032 dice1: 0.17811703681946
Output for 7.0.16
dice1: 0.17174386978149 dice1: 0.1860830783844
Output for 7.0.15
dice1: 0.16638112068176 dice1: 0.17611503601074
Output for 7.0.14
dice1: 0.21113896369934 dice1: 0.24475383758545
Output for 7.0.13
dice1: 0.24420976638794 dice1: 0.24059009552002
Output for 7.0.12
dice1: 0.16318106651306 dice1: 0.1870219707489
Output for 7.0.11
dice1: 0.15966486930847 dice1: 0.17235803604126
Output for 7.0.10
dice1: 0.24412989616394 dice1: 0.19259405136108
Output for 7.0.9
dice1: 0.18117904663086 dice1: 0.19458198547363
Output for 7.0.8
dice1: 0.15552091598511 dice1: 0.1576509475708
Output for 7.0.7
dice1: 0.15703701972961 dice1: 0.23914480209351
Output for 7.0.6
dice1: 0.15890789031982 dice1: 0.15629696846008
Output for 7.0.5
dice1: 0.22177791595459 dice1: 0.21757578849792
Output for 7.0.4
dice1: 0.18169403076172 dice1: 0.18228101730347
Output for 7.0.3
dice1: 0.23982715606689 dice1: 0.23232889175415
Output for 7.0.2
dice1: 0.18859386444092 dice1: 0.16083288192749
Output for 7.0.1
dice1: 0.19697403907776 dice1: 0.17394304275513
Output for 7.0.0
dice1: 0.24388408660889 dice1: 0.23926711082458
Output for 5.6.40
dice1: 0.33570098876953 dice1: 0.36853504180908
Output for 5.6.39
dice1: 0.36685109138489 dice1: 0.34222793579102
Output for 5.6.38
dice1: 0.43173384666443 dice1: 0.35844707489014
Output for 5.6.37
dice1: 0.35403513908386 dice1: 0.34771013259888
Output for 5.6.36
dice1: 0.43460988998413 dice1: 0.33752012252808
Output for 5.6.35
dice1: 0.3622739315033 dice1: 0.38826894760132
Output for 5.6.34
dice1: 0.35623002052307 dice1: 0.35674905776978
Output for 5.6.33
dice1: 0.4544460773468 dice1: 0.41113615036011
Output for 5.6.32
dice1: 0.46691703796387 dice1: 0.35435795783997
Output for 5.6.31
dice1: 0.40040111541748 dice1: 0.34910583496094
Output for 5.6.30
dice1: 0.3874990940094 dice1: 0.43721508979797
Output for 5.6.29
dice1: 0.42729020118713 dice1: 0.43192791938782
Output for 5.6.28
dice1: 0.36415886878967 dice1: 0.36099720001221
Output for 5.6.27
dice1: 0.43561100959778 dice1: 0.33389902114868
Output for 5.6.26
dice1: 0.42503213882446 dice1: 0.29483199119568
Output for 5.6.25
dice1: 0.34205293655396 dice1: 0.34284090995789
Output for 5.6.24
dice1: 0.35771989822388 dice1: 0.34472012519836
Output for 5.6.23
dice1: 0.36637401580811 dice1: 0.3051700592041
Output for 5.6.22
dice1: 0.36815595626831 dice1: 0.34562397003174
Output for 5.6.21
dice1: 0.38826680183411 dice1: 0.33369517326355
Output for 5.6.20
dice1: 0.46013498306274 dice1: 0.47698903083801
Output for 5.6.19
dice1: 0.37740588188171 dice1: 0.32616519927979
Output for 5.6.18
dice1: 0.34887719154358 dice1: 0.46726202964783
Output for 5.6.17
dice1: 0.35760092735291 dice1: 0.3722140789032
Output for 5.6.16
dice1: 0.41907978057861 dice1: 0.34706807136536
Output for 5.6.15
dice1: 0.39831590652466 dice1: 0.34573984146118
Output for 5.6.14
dice1: 0.33555603027344 dice1: 0.31785798072815
Output for 5.6.13
dice1: 0.45786213874817 dice1: 0.48349499702454
Output for 5.6.12
dice1: 0.33539795875549 dice1: 0.33106994628906
Output for 5.6.11
dice1: 0.49266314506531 dice1: 0.3859920501709
Output for 5.6.10
dice1: 0.31892585754395 dice1: 0.36881017684937
Output for 5.6.9
dice1: 0.35452198982239 dice1: 0.34561395645142
Output for 5.6.8
dice1: 0.3198869228363 dice1: 0.35911893844604
Output for 5.6.7
dice1: 0.40639805793762 dice1: 0.29605102539062
Output for 5.6.6
dice1: 0.42549610137939 dice1: 0.39813494682312
Output for 5.6.5
dice1: 0.367999792099 dice1: 0.36075711250305
Output for 5.6.4
dice1: 0.4778778553009 dice1: 0.37236094474792
Output for 5.6.3
dice1: 0.32580590248108 dice1: 0.31523394584656
Output for 5.6.2
dice1: 0.34658598899841 dice1: 0.34530186653137
Output for 5.6.1
dice1: 0.33480191230774 dice1: 0.30185103416443
Output for 5.6.0
dice1: 0.40975093841553 dice1: 0.33601689338684
Output for 5.5.0 - 5.5.38
Parse error: syntax error, unexpected '.' in /in/ZpriQ on line 222
Process exited with code 255.
Output for 5.4.0 - 5.4.45
Parse error: syntax error, unexpected '.', expecting ')' in /in/ZpriQ on line 222
Process exited with code 255.

preferences:
180.59 ms | 401 KiB | 242 Q