SplObjectStorage is the object set PHP does not advertise

Objects cannot be array keys, so checking whether an object is already in a collection usually turns into in_array($obj, $list, true) — a linear scan that gets slower with every element. SplObjectStorage is a hash set keyed by object identity, so containment is constant time.

$visited = new SplObjectStorage();

foreach ($nodes as $node) {
    if ($visited->contains($node)) {
        continue;
    }

    $visited->attach($node);
    $this->walk($node);
}

It also doubles as an object-keyed map: $storage[$obj] = $data attaches arbitrary data to an object without touching the object itself. The catch is that it holds a strong reference, so a long-lived storage will keep every object it has ever seen alive — call detach() or let the storage go out of scope.