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->invoke($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); foreach ($paramClasses as $class) { if (!empty($args)) for ($i = 0; $i < count($args); $i++) { if ($class && $args[$i] instanceof $class) { yield array_splice($args, $i, 1)[0]; continue 2; } } if (!empty($subs) && isset($subs[$class])) yield is_string($subs[$class]) ? $this->create($subs[$class]) : $this->expand($subs[$class]); else if (!empty($class)) yield $this->create($class, $share, !empty($rule->newInstances) && in_array(strtolower($class), array_map('strtolower', $rule->newInstances))); else if (!empty($args)) yield array_shift($args); } }; } } $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.098487854003906 dice1: 0.13987302780151
Output for 7.4.0
dice1: 0.15138792991638 dice1: 0.17864298820496
Output for 7.3.13
dice1: 0.11382603645325 dice1: 0.12907004356384
Output for 7.3.12
dice1: 0.15213298797607 dice1: 0.17740392684937
Output for 7.3.11
dice1: 0.15152597427368 dice1: 0.17994999885559
Output for 7.3.10
dice1: 0.091226816177368 dice1: 0.15614104270935
Output for 7.3.9
dice1: 0.093512058258057 dice1: 0.13041520118713
Output for 7.3.8
dice1: 0.09822416305542 dice1: 0.11356115341187
Output for 7.3.7
dice1: 0.1145920753479 dice1: 0.10931205749512
Output for 7.3.6
dice1: 0.11103105545044 dice1: 0.12623596191406
Output for 7.3.5
dice1: 0.091375112533569 dice1: 0.10761380195618
Output for 7.3.4
dice1: 0.10699391365051 dice1: 0.132248878479
Output for 7.3.3
dice1: 0.11683893203735 dice1: 0.10931515693665
Output for 7.3.2
dice1: 0.097058773040771 dice1: 0.11345314979553
Output for 7.3.1
dice1: 0.10513186454773 dice1: 0.11128401756287
Output for 7.3.0
dice1: 0.097787141799927 dice1: 0.17400002479553
Output for 7.2.26
dice1: 0.12713503837585 dice1: 0.1342499256134
Output for 7.2.25
dice1: 0.18664193153381 dice1: 0.18514013290405
Output for 7.2.24
dice1: 0.15007781982422 dice1: 0.13468408584595
Output for 7.2.23
dice1: 0.13126015663147 dice1: 0.16795492172241
Output for 7.2.22
dice1: 0.1794228553772 dice1: 0.20521378517151
Output for 7.2.21
dice1: 0.13047289848328 dice1: 0.15037894248962
Output for 7.2.20
dice1: 0.11342811584473 dice1: 0.13013219833374
Output for 7.2.19
dice1: 0.12611794471741 dice1: 0.14485096931458
Output for 7.2.18
dice1: 0.11282587051392 dice1: 0.17422795295715
Output for 7.2.17
dice1: 0.12418699264526 dice1: 0.13054919242859
Output for 7.2.16
dice1: 0.17545199394226 dice1: 0.20595502853394
Output for 7.2.15
dice1: 0.14497208595276 dice1: 0.15172719955444
Output for 7.2.14
dice1: 0.13191604614258 dice1: 0.1278350353241
Output for 7.2.13
dice1: 0.14213895797729 dice1: 0.20148801803589
Output for 7.2.12
dice1: 0.15009999275208 dice1: 0.20444393157959
Output for 7.2.11
dice1: 0.17492985725403 dice1: 0.12817311286926
Output for 7.2.10
dice1: 0.11300086975098 dice1: 0.12781000137329
Output for 7.2.9
dice1: 0.1764509677887 dice1: 0.1506769657135
Output for 7.2.8
dice1: 0.16740012168884 dice1: 0.12847495079041
Output for 7.2.7
dice1: 0.16094493865967 dice1: 0.2038049697876
Output for 7.2.6
dice1: 0.1740939617157 dice1: 0.15483522415161
Output for 7.2.5
dice1: 0.11376595497131 dice1: 0.13774704933167
Output for 7.2.4
dice1: 0.12278509140015 dice1: 0.15810799598694
Output for 7.2.3
dice1: 0.17562317848206 dice1: 0.20487904548645
Output for 7.2.2
dice1: 0.11256289482117 dice1: 0.13894414901733
Output for 7.2.1
dice1: 0.17254018783569 dice1: 0.17473006248474
Output for 7.2.0
dice1: 0.11739301681519 dice1: 0.1281111240387
Output for 7.1.33
dice1: 0.16297101974487 dice1: 0.20281910896301
Output for 7.1.32
dice1: 0.22570204734802 dice1: 0.22528791427612
Output for 7.1.31
dice1: 0.16521692276001 dice1: 0.18235301971436
Output for 7.1.30
dice1: 0.21394801139832 dice1: 0.21149301528931
Output for 7.1.29
dice1: 0.15164494514465 dice1: 0.19760799407959
Output for 7.1.28
dice1: 0.21991896629333 dice1: 0.25322198867798
Output for 7.1.27
dice1: 0.16892099380493 dice1: 0.19208002090454
Output for 7.1.26
dice1: 0.17674088478088 dice1: 0.18678593635559
Output for 7.1.25
dice1: 0.2209050655365 dice1: 0.22902202606201
Output for 7.1.24
dice1: 0.18927311897278 dice1: 0.18939208984375
Output for 7.1.23
dice1: 0.18588614463806 dice1: 0.17119288444519
Output for 7.1.22
dice1: 0.16437411308289 dice1: 0.1899311542511
Output for 7.1.21
dice1: 0.14704418182373 dice1: 0.1802179813385
Output for 7.1.20
dice1: 0.18621206283569 dice1: 0.18798089027405
Output for 7.1.19
dice1: 0.22329092025757 dice1: 0.21168279647827
Output for 7.1.18
dice1: 0.21025800704956 dice1: 0.202388048172
Output for 7.1.17
dice1: 0.17316818237305 dice1: 0.16695380210876
Output for 7.1.16
dice1: 0.16573596000671 dice1: 0.18766283988953
Output for 7.1.15
dice1: 0.14779114723206 dice1: 0.1667308807373
Output for 7.1.14
dice1: 0.16358208656311 dice1: 0.20326018333435
Output for 7.1.13
dice1: 0.19689798355103 dice1: 0.26251888275146
Output for 7.1.12
dice1: 0.21196484565735 dice1: 0.16630697250366
Output for 7.1.11
dice1: 0.17734885215759 dice1: 0.24361896514893
Output for 7.1.10
dice1: 0.19281196594238 dice1: 0.25317096710205
Output for 7.1.9
dice1: 0.17797017097473 dice1: 0.19722414016724
Output for 7.1.8
dice1: 0.22784900665283 dice1: 0.19921398162842
Output for 7.1.7
dice1: 0.2182788848877 dice1: 0.24824595451355
Output for 7.1.6
dice1: 0.1782910823822 dice1: 0.25451493263245
Output for 7.1.5
dice1: 0.1697199344635 dice1: 0.19603204727173
Output for 7.1.4
dice1: 0.16944789886475 dice1: 0.25401496887207
Output for 7.1.3
dice1: 0.20213508605957 dice1: 0.17531085014343
Output for 7.1.2
dice1: 0.14584302902222 dice1: 0.22098398208618
Output for 7.1.1
dice1: 0.19878911972046 dice1: 0.26252388954163
Output for 7.1.0
dice1: 0.16470313072205 dice1: 0.19106197357178
Output for 7.0.33
dice1: 0.1669590473175 dice1: 0.20406699180603
Output for 7.0.32
dice1: 0.16143894195557 dice1: 0.24043011665344
Output for 7.0.31
dice1: 0.17905783653259 dice1: 0.21863317489624
Output for 7.0.30
dice1: 0.17407512664795 dice1: 0.2121160030365
Output for 7.0.29
dice1: 0.21732401847839 dice1: 0.24104595184326
Output for 7.0.28
dice1: 0.25198793411255 dice1: 0.20294904708862
Output for 7.0.27
dice1: 0.18872308731079 dice1: 0.22497701644897
Output for 7.0.26
dice1: 0.23223209381104 dice1: 0.21724987030029
Output for 7.0.25
dice1: 0.18308186531067 dice1: 0.19200491905212
Output for 7.0.24
dice1: 0.25629687309265 dice1: 0.25819516181946
Output for 7.0.23
dice1: 0.20296692848206 dice1: 0.21627998352051
Output for 7.0.22
dice1: 0.2423210144043 dice1: 0.29699397087097
Output for 7.0.21
dice1: 0.17935800552368 dice1: 0.19967103004456
Output for 7.0.20
dice1: 0.24908995628357 dice1: 0.22483515739441
Output for 7.0.19
dice1: 0.17351198196411 dice1: 0.25399208068848
Output for 7.0.18
dice1: 0.16363096237183 dice1: 0.18916010856628
Output for 7.0.17
dice1: 0.25338506698608 dice1: 0.24702882766724
Output for 7.0.16
dice1: 0.18567609786987 dice1: 0.22126698493958
Output for 7.0.15
dice1: 0.22270202636719 dice1: 0.21089601516724
Output for 7.0.14
dice1: 0.25175404548645 dice1: 0.23890900611877
Output for 7.0.13
dice1: 0.25243401527405 dice1: 0.23451900482178
Output for 7.0.12
dice1: 0.19222402572632 dice1: 0.22430992126465
Output for 7.0.11
dice1: 0.17708992958069 dice1: 0.20299506187439
Output for 7.0.10
dice1: 0.22588181495667 dice1: 0.29941606521606
Output for 7.0.9
dice1: 0.18240094184875 dice1: 0.21848106384277
Output for 7.0.8
dice1: 0.23680901527405 dice1: 0.29135799407959
Output for 7.0.7
dice1: 0.25037407875061 dice1: 0.20935201644897
Output for 7.0.6
dice1: 0.20121192932129 dice1: 0.21193504333496
Output for 7.0.5
dice1: 0.249675989151 dice1: 0.30051302909851
Output for 7.0.4
dice1: 0.18359708786011 dice1: 0.21011209487915
Output for 7.0.3
dice1: 0.22176718711853 dice1: 0.19516205787659
Output for 7.0.2
dice1: 0.16812205314636 dice1: 0.20349097251892
Output for 7.0.1
dice1: 0.25118398666382 dice1: 0.20812296867371
Output for 7.0.0
dice1: 0.22596120834351 dice1: 0.18937301635742
Output for 5.6.40
dice1: 0.32786202430725 dice1: 0.37826704978943
Output for 5.6.39
dice1: 0.39960885047913 dice1: 0.51919794082642
Output for 5.6.38
dice1: 0.31560111045837 dice1: 0.47677397727966
Output for 5.6.37
dice1: 0.36726498603821 dice1: 0.46855497360229
Output for 5.6.36
dice1: 0.35541200637817 dice1: 0.48911595344543
Output for 5.6.35
dice1: 0.33558297157288 dice1: 0.5508828163147
Output for 5.6.34
dice1: 0.40856885910034 dice1: 0.43115401268005
Output for 5.6.33
dice1: 0.42089700698853 dice1: 0.54299306869507
Output for 5.6.32
dice1: 0.38715577125549 dice1: 0.44865083694458
Output for 5.6.31
dice1: 0.3379819393158 dice1: 0.40429615974426
Output for 5.6.30
dice1: 0.31940197944641 dice1: 0.38083100318909
Output for 5.6.29
dice1: 0.31409811973572 dice1: 0.56529307365417
Output for 5.6.28
dice1: 0.40390086174011 dice1: 0.43451404571533
Output for 5.6.27
dice1: 0.31348180770874 dice1: 0.38778495788574
Output for 5.6.26
dice1: 0.41605496406555 dice1: 0.52028107643127
Output for 5.6.25
dice1: 0.48804306983948 dice1: 0.4844069480896
Output for 5.6.24
dice1: 0.31269383430481 dice1: 0.38869190216064
Output for 5.6.23
dice1: 0.31069993972778 dice1: 0.45700883865356
Output for 5.6.22
dice1: 0.40988802909851 dice1: 0.46039915084839
Output for 5.6.21
dice1: 0.31339597702026 dice1: 0.37965297698975
Output for 5.6.20
dice1: 0.49491286277771 dice1: 0.43242192268372
Output for 5.6.19
dice1: 0.36661815643311 dice1: 0.39101195335388
Output for 5.6.18
dice1: 0.42260694503784 dice1: 0.4585428237915
Output for 5.6.17
dice1: 0.46696901321411 dice1: 0.47130393981934
Output for 5.6.16
dice1: 0.34119510650635 dice1: 0.39710998535156
Output for 5.6.15
dice1: 0.37250113487244 dice1: 0.38285613059998
Output for 5.6.14
dice1: 0.4230170249939 dice1: 0.62871408462524
Output for 5.6.13
dice1: 0.339271068573 dice1: 0.5475709438324
Output for 5.6.12
dice1: 0.36918520927429 dice1: 0.45436000823975
Output for 5.6.11
dice1: 0.50067710876465 dice1: 0.52846598625183
Output for 5.6.10
dice1: 0.3199610710144 dice1: 0.61172318458557
Output for 5.6.9
dice1: 0.46619296073914 dice1: 0.54691290855408
Output for 5.6.8
dice1: 0.32936882972717 dice1: 0.43125700950623
Output for 5.6.7
dice1: 0.51431584358215 dice1: 0.45067691802979
Output for 5.6.6
dice1: 0.4163990020752 dice1: 0.44631195068359
Output for 5.6.5
dice1: 0.48364996910095 dice1: 0.47469305992126
Output for 5.6.4
dice1: 0.34692192077637 dice1: 0.39186382293701
Output for 5.6.3
dice1: 0.31700301170349 dice1: 0.40292811393738
Output for 5.6.2
dice1: 0.32736206054688 dice1: 0.39995193481445
Output for 5.6.1
dice1: 0.3614809513092 dice1: 0.38137412071228
Output for 5.6.0
dice1: 0.38981008529663 dice1: 0.38146305084229
Output for 5.4.0 - 5.4.45, 5.5.0 - 5.5.38
Parse error: syntax error, unexpected '.' in /in/6TKDp on line 220
Process exited with code 255.

preferences:
158.69 ms | 402 KiB | 242 Q