3v4l.org

run code in 500+ PHP versions simultaneously
<?php class a { public readonly b $b; function __construct(public string $name) { $this->b = new b($this); } function hoohoo(): mixed { return $this->b; } } class b { use weakObjReference; function __construct(a $container) { $this->weakReference($container, 'container'); // $this->container "created" } function heehee($name): mixed { $x = $name . ', '. $this->container->name; return $x; } } $a = new a('world 1'); var_dump($a->hoohoo()->heehee('hello')); // EXAMPLE 1 var_dump((new a('world 2'))->hoohoo()->heehee('good afternoon')); // EXAMPLE 2. trait weakObjReference { // Door containersnt als weak references op te slaan, voorkom je dat container references reference counts verhogen waardoor // cache niet geleegd wordt "want deze instance wordt nog gebruikt". // Ook nuttig bij debugging aangezien bij var_debug c.s. niet het hele object wordt weergegeven // Gebruik: kan gewone eigenschappen vervangen. // $obj->weakReference($containingObject, 'container'); // Vanaf nu bruikbaar: // $obj->container // NOTE: ook bruikbaar voor grandcontainers, sibling containers, etc. protected array $weakObjectStorage = []; protected function weakReference(object $container, string $propertyName='containerc'/*, bool $serializeable=true*/) { $this->weakObjectStorage[$propertyName] = new weakObjReferenceStorage($container); } // Have your own __get? Let it call __getWeakRef() to see if the container is needed function __get(string $propName) { if (! array_key_exists($propName, $this->weakObjectStorage)) { if ( method_exists($this, $propName)) trigger_error("Error in ".__CLASS__. ": unknown property $propName, did you mean the method ".__CLASS__."::$propName() ?", E_USER_ERROR); trigger_error("Error in ".__CLASS__. ": unknown property '$propName'", E_USER_ERROR); } return $this->__getWeakRef($propName); } // Alleen nodig voor in eigen __get() routines function __getWeakRef(string $propName): ?object { if (isset($this->weakObjectStorage[$propName])) { $r = $this->weakObjectStorage[$propName]->get() ; return $r; } return null ; } function __isset(string $propName): bool { return isset($this->$propName) || $this->__issetWeakRef($propName) ; } // Have your own __isset? Let it call __issetWeakRef() to see if it is set as a weak reference function __issetWeakRef(string $propName): bool { return isset($this->weakObjectStorage[$propName]); } private array $temporaryStrongReferences = []; // Temporarily strengthen the reference public function temporaryStrong($property) { if (isset($this->weakObjectStorage[$property])) { $this->temporaryStrongReferences[$property] = $this->weakObjectStorage[$property]->get(); } } // Revert to weak reference public function weakAgain($property) { unset($this->temporaryStrongReferences[$property]); } } class weakObjReferenceStorage { private readonly WeakReference $weakRef; function __construct(object $object) { if ( get_class($object) == 'WeakReference') // VDZ $this->WeakRef = $object; else $this->weakRef = WeakReference::create($object); } public function get(): object { return $this->weakRef->get(); } function __serialize() { // serialize the original object because weakreferences cannot be serialised return ['weakRef'=>$this->weakRef->get()]; } function __unserialize(array $array) { // restore as a weak reference $this->weakRef = WeakReference::create($array['weakRef']); } }
Output for 8.1.0 - 8.1.34, 8.2.0 - 8.2.30, 8.3.0 - 8.3.30, 8.4.1 - 8.4.18, 8.5.0 - 8.5.3
string(14) "hello, world 1" Fatal error: Uncaught TypeError: weakObjReferenceStorage::get(): Return value must be of type object, null returned in /in/7DpN2:124 Stack trace: #0 /in/7DpN2(77): weakObjReferenceStorage->get() #1 /in/7DpN2(71): b->__getWeakRef('container') #2 /in/7DpN2(27): b->__get('container') #3 /in/7DpN2(35): b->heehee('good afternoon') #4 {main} thrown in /in/7DpN2 on line 124
Process exited with code 255.

preferences:
56.5 ms | 1022 KiB | 4 Q