Browsing
Walk the address space one level, all levels, or with continuation. browse() is the lowest-friction call; browseAll() and browseRecursive() handle paginated and tree traversals.
A Browse service call asks the server: "starting from this node,
which references match my criteria and which target nodes do they
point to?". The reply is a list of ReferenceDescription items —
each describes one outgoing reference plus the (decoded) target node.
This library exposes three browse shapes — browse(),
browseAll(), browseRecursive() — plus two pagination primitives.
Pick one by intent:
| You want | Use |
|---|---|
| One level, first page only | browse() |
| One level, all pages | browseAll() |
| Entire subtree | browseRecursive() |
| Manual continuation control | browseWithContinuation() + browseNext() |
browse()
foreach ($client->browse('i=85') as $ref) {
printf(
"%-30s %-12s %s\n",
$ref->displayName->text,
$ref->nodeClass->name,
$ref->nodeId
);
}
browse() returns the first page of references. For most servers,
"a folder with a few children" fits in one page and there is nothing
more to fetch. For wide nodes (a server with thousands of devices
under one root), you will see only the first ~100–1000 entries; use
browseAll() or browseWithContinuation().
Filters
| Argument | Effect |
|---|---|
$direction |
Forward (default), Inverse, or Both. Inverse follows references pointing at the node. |
$includeSubtypes |
When true (default), references whose ReferenceTypeId is a subtype of the standard reference types are included. Set false to follow a single specific reference type. |
$nodeClassMask |
Bitmask filter on the target node's class. 0 = all. Combine NodeClass enum values with |. |
use PhpOpcua\Client\Types\NodeClass;
$variables = $client->browse(
'ns=2;s=Devices',
nodeClassMask: NodeClass::Variable->value
);
browseAll()
browseAll() follows continuation points until the server reports
done. The signature mirrors browse():
$all = $client->browseAll('ns=2;s=Devices'); // every immediate child
Behind the scenes the client issues Browse, then BrowseNext on the
continuation point repeatedly until the server returns no further
items. Each follow-up call respects the same $useCache flag.
browseRecursive()
For tree walks, browseRecursive() traverses children-of-children up
to a configurable depth, with built-in cycle detection:
$tree = $client->browseRecursive('ns=2;s=Devices', maxDepth: 3);
// $tree is a BrowseNode — each node has a reference and an array of children.
walk($tree, depth: 0);
function walk(BrowseNode $node, int $depth): void
{
echo str_repeat(' ', $depth) . $node->reference->displayName->text . "\n";
foreach ($node->getChildren() as $child) {
walk($child, $depth + 1);
}
}
$maxDepth = nullfalls back to the builder-wide default (setDefaultBrowseMaxDepth(), ships at4). Cap it deliberately for large address spaces — an OPC UA server with 50 000 nodes will exhaust memory long before the network does.- Cycle detection tracks NodeIds already visited and short-circuits.
- Internally, each level runs
browseAll()and inherits its caching.
See Recipes · Browsing recursively for streaming alternatives.
Manual continuation
When you need finer control — incremental loading in a UI, time- bounded discovery — drop to the lower-level pair:
$page = $client->browseWithContinuation('ns=2;s=Devices');
foreach ($page->references as $ref) {
process($ref);
}
while ($page->continuationPoint !== null) {
$page = $client->browseNext($page->continuationPoint);
foreach ($page->references as $ref) {
process($ref);
}
}
browseWithContinuation() returns a BrowseResultSet with both the
current page and an optional continuation point. browseNext() takes
that token and returns the next page. The continuation point is opaque
and unique to the originating call — pass it back unchanged.
Caching
By default every browse call caches its result keyed by endpoint URL,
NodeId, direction, includeSubtypes, and nodeClassMask. Cache hits fire
the CacheHit event, misses fire CacheMiss. Bypass per call with
useCache: false; flush all entries with $client->flushCache() or
invalidate one node with $client->invalidateCache($nodeId).
Browse events
| Event | When |
|---|---|
NodeBrowsed |
After every successful browse — payload carries the node id, direction, and reference count |
CacheHit / CacheMiss |
Cache observation events |
What to read next
- Operations · Resolving paths —
translateBrowsePaths()/resolveNodeId(), which use Browse-like semantics to turn/Objects/Server/…strings into NodeIds. - Types · NodeId — the structure of the
identifiers returned in
ReferenceDescription.