3v4l.org

run code in 300+ PHP versions simultaneously
<?php class Reference { private static $DATA = []; private $index = 0; public function __construct($value) { // cannot create a reference of a reference if ($value instanceof self) { $this->index = $value->index; } else { $this->index = count(self::$DATA); self::$DATA[$this->index] = $value; } } public function get() { return self::$DATA[$this->index]; } public function set($value) { self::$DATA[$this->index] = $value; } } $x = [1, 2, 3]; // foreach($x as &$ref) { ... } /* $x[0] */ $x[0] = new Reference($x[0]); // Reference#0(index 0) = 1 $ref = clone $x[0]; // Reference#1(index 0) $ref->set($ref->get() + 100); // set index 0 = 101 /* $x[1] */ $x[1] = new Reference($x[1]); // Reference#2(index 1) = 2 $ref = clone $x[1]; // Reference#3(index 1) $x[0] = $x[0]->get(); // without $ref, $x[0] is the only reference to its value and demoted back to a value $ref->set($ref->get() + 100); // set index 1 = 101 /* $x[2] */ $x[2] = new Reference($x[2]); // Reference#4(index 2) = 3 $ref = clone $x[2]; // Reference#5(index 2) $x[1] = $x[1]->get(); // demoted $ref->set($ref->get() + 100); // set index 2 = 103 // end foreach /* $x is [101, 102, Reference#4(index 2)] */ /* $ref remains as Reference#5(index 2) */ $b = $x; // $b[0] = clone $x[0]; - except $x[0] is an integer so this was automatic // $b[1] = clone $x[1]; - same $b[2] = clone $x[2]; // creating a copy of what was in $x[2] /* $b is [101, 102, Reference#6(index 2)] - a different Reference as $x[2] and $ref but the same underlying value */ $b[0] = 0; // foreach($x as &$ref) { ... } /* $x[0] */ $x[0] = new Reference($x[0]); // Reference#7(index 3) = 101 $ref = clone $x[0]; // Reference#8(index 3) $ref->set($ref->get() + 100); // set index 3 = 201 /* $x[1] */ $x[1] = new Reference($x[1]); // Reference#9(index 4) = 102 $ref = clone $x[1]; // Reference#10(index 4) $x[0] = $x[0]->get(); // demoted $ref->set($ref->get() + 100); // set index 4 = 202 /* $x[2] */ // $x[2] = new Reference($x[2]); // - except $x[2] is already Reference#4(index 2) $ref = clone $x[2]; // Reference#11(index 2) $x[1] = $x[1]->get(); // demoted $ref->set($ref->get() + 100); // set index 2 = 203 // end foreach /* $x is [201, 202, Reference#4(index 2)] */ /* $ref remains as Reference#11(index 2) */ /* $b was not modified during the foreach and still contains [0, 102, Reference#6(index 2)] */ /* however the underlying value of the Reference did change */ // var_dump($b); var_dump([$b[0], $b[1], $b[2]->get()]);

preferences:
53.98 ms | 402 KiB | 5 Q