3v4l.org

run code in 300+ PHP versions simultaneously
<?php class RecursionDetector { private array $obj_ref_stack = []; private array $arr_ref_stack = []; public function detect(&$val): bool { switch (gettype($val)) { case 'object': $hash = spl_object_hash($val); var_dump($hash); if (isset($this->obj_ref_stack[$hash])) { debug_print_backtrace(); return true; } $this->obj_ref_stack[$hash] = true; $copy = (array) $val; break; case 'array': $ref = ReflectionReference::fromArrayElement([&$var], 0)->getId(); if (isset($this->arr_ref_stack[$ref])) { debug_print_backtrace(); return true; } $this->arr_ref_stack[$ref] = true; $copy = $val; break; default: return false; } $recurse = false; foreach ($copy as $k => $_) { if ($this->detect($copy[$k])) { $recurse = true; break; } } switch (gettype($val)) { case 'object': unset($this->obj_ref_stack[$hash]); break; case 'array': unset($this->arr_ref_stack[$ref]); break; } return $recurse; } } $d = new RecursionDetector(); class X { public array $y = []; } $x = new X(); $r = new ReflectionClass('X'); $z = $r->newLazyProxy(fn() => $x); $x->y[] = [[$z]]; $_ = $z->y; var_dump($x, $z); var_dump($d->detect($x)); var_dump($d->detect($z));
Output for git.master_jit, git.master
object(X)#2 (1) { ["y"]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> lazy proxy object(X)#5 (1) { ["instance"]=> *RECURSION* } } } } } lazy proxy object(X)#5 (1) { ["instance"]=> object(X)#2 (1) { ["y"]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> *RECURSION* } } } } } string(32) "00000000000000020000000000000000" string(32) "00000000000000050000000000000000" string(32) "00000000000000050000000000000000" #0 /in/Ad9CN(35): RecursionDetector->detect(Object(X)) #1 /in/Ad9CN(35): RecursionDetector->detect(Array) #2 /in/Ad9CN(35): RecursionDetector->detect(Array) #3 /in/Ad9CN(35): RecursionDetector->detect(Array) #4 /in/Ad9CN(35): RecursionDetector->detect(Object(X)) #5 /in/Ad9CN(35): RecursionDetector->detect(Array) #6 /in/Ad9CN(35): RecursionDetector->detect(Array) #7 /in/Ad9CN(35): RecursionDetector->detect(Array) #8 /in/Ad9CN(69): RecursionDetector->detect(Object(X)) bool(true) string(32) "00000000000000050000000000000000" string(32) "00000000000000050000000000000000" #0 /in/Ad9CN(35): RecursionDetector->detect(Object(X)) #1 /in/Ad9CN(35): RecursionDetector->detect(Array) #2 /in/Ad9CN(35): RecursionDetector->detect(Array) #3 /in/Ad9CN(35): RecursionDetector->detect(Array) #4 /in/Ad9CN(70): RecursionDetector->detect(Object(X)) bool(true)

This tab shows result from various feature-branches currently under review by the php developers. Contact me to have additional branches featured.

Active branches

Archived branches

Once feature-branches are merged or declined, they are no longer available. Their functionality (when merged) can be viewed from the main output page


preferences:
32.78 ms | 409 KiB | 5 Q