WeakMap and WeakReference

A normal variable, array entry, or property holding an object counts as a reference to it, keeping it alive: PHP won't garbage-collect an object while anything still points to it. A WeakReference (added in PHP 7.4) is different — it points to an object without counting as a reference, so the object can still be destroyed as if the weak reference didn't exist. Create one with WeakReference::create($obj), and read the object back, while it is still alive, with ->get().

<?php
class Foo {}

$obj = new Foo();
$ref = WeakReference::create($obj);

var_dump($ref->get() instanceof Foo);

unset($obj);
gc_collect_cycles();

var_dump($ref->get());
?>

bool(true) NULL
A WeakMap (added in PHP 8.0) is an array-like collection that uses objects as keys, and behaves the same way: storing an object as a key does not keep that object alive. Once nothing else in the program references the key object, PHP automatically drops both the key and its value from the map. This makes WeakMap a natural fit for attaching extra data — metadata, cached results, event listeners — to objects whose lifetime you don't control, without leaking memory. The example below stores one entry, then removes the only other reference to the key object and forces collection with gc_collect_cycles() to show the entry vanishing from the map.

<?php
class Foo {}

$map = new WeakMap();
$obj = new Foo();
$map[$obj] = 'data for obj';

echo "Count before: ", count($map), "\n";

unset($obj);
gc_collect_cycles();

echo "Count after: ", count($map), "\n";
?>

Count before: 1 Count after: 0
Aside from keys having to be objects rather than scalars, a WeakMap is used just like a regular array: reading, writing, isset(), and unset() on $map[$obj] all work exactly as they would on an array keyed by strings or integers.