Components showcase
Docs · Getting started

Introduction

A pure-PHP OPC UA client. It speaks the binary protocol over TCP, manages secure channels, sessions and cryptography without relying on any C/C++ extension.

What is it?

php-opcua/opcua-client is an OPC UA client implementation written entirely in PHP. The library covers the OPC UA binary protocol, secure channel negotiation, session management and the cryptographic primitives required to talk to industrial servers — without any native dependencies beyond ext-openssl.

Read & write attribute values, browse the address space, call methods, subscribe to monitored items and consume historical data — all from idiomatic PHP code.

Requirements

  • PHP ≥ 8.2
  • ext-openssl
  • Optional: any PSR-3 logger implementation for diagnostic output

Installation

Install the package with Composer:

bash terminal
composer require php-opcua/opcua-client

Quick Start

Open a connection, read a single attribute, close — three lines of plumbing:

PHP examples/quick-start.php
<?php

use PhpOpcua\Client\ClientBuilder;
use PhpOpcua\Client\Types\NodeId;
use PhpOpcua\Client\Types\StatusCode;

$client = ClientBuilder::create()
    ->connect('opc.tcp://localhost:4840');

$dataValue = $client->read(NodeId::numeric(0, 2259));

if ($dataValue->status->equals(StatusCode::good())) {
    echo $dataValue->value;
}

$client->disconnect();

Features

  • 47 granular protocol events, observable through PSR-14 dispatchers
  • 10 security policies covering Sign and Sign&Encrypt at every supported strength
  • Encoder/decoder for all standard OPC UA types — including extension objects
  • Subscription helpers with automatic re-publish and acknowledgement bookkeeping
  • Pluggable trust-store, transport and module subsystems for advanced integrations

Architecture

The library is layered: a thin Client facade composes a Session running on top of a SecureChannel, which itself rides a binary Transport. Encoding and security are isolated subsystems used at every layer.

text layer diagram
Client
└── Session
    └── SecureChannel
        ├── Transport (TCP)
        ├── Encoding (binary, XML)
        └── Security (policies, signing, encryption)
Doc blocks · reference

The blocks below are the reusable primitives every page in this documentation will rely on. Copy & adapt them when authoring new pages.

Callouts

Five variants for inline asides. Use note for plain context, tip to share an idiomatic shortcut, warning for non-obvious gotchas, danger for footguns, info for neutral cross-references.

Note

Sessions are bound to a transport; reusing a session after the channel closes will throw SessionClosedException.

Idiomatic

Prefer ClientBuilder::create() over instantiating Client directly — the builder wires the default transport, security policy and PSR-3 logger for you.

Warning

The server's certificate is not validated when SecurityPolicy::None is selected. Restrict that policy to local development.

Footgun

Calling $client->disconnect() from inside a subscription callback deadlocks the publish loop. Schedule the disconnect on the next tick instead.

Info

Looking for asynchronous I/O? See the ReactPHP transport adapter shipped under php-opcua/transport-react.

Do / Don't

Pair recommended and discouraged patterns side-by-side. Useful in "best practices" sections and migration guides.

Do

Resolve NodeId via the typed factories:

NodeId::numeric(0, 2259)

They validate the namespace index at construction time and produce a value object that survives serialization.

Don't

Don't string-format identifiers by hand:

"ns=0;i=2259"

The parser is unforgiving and silent failures will look like "no such node" at runtime.

Version notices

Inline pills for "added / changed / deprecated / removed" notes, modeled after Symfony's versionadded directive.

Added in v4.3.0 Changed in v4.2.0 Deprecated in v4.0.0 · 2025-08 Removed in v5.0.0

Inline, they read like this: Added in v4.3.0 the $timeout parameter accepts 0 to disable the watchdog.

Method & parameters

Signature card followed by a typed parameter list. The pattern doubles as cheap API reference until we have a proper reflection-based generator.

method · public
returns DataValue
$client->read(NodeId $node, ?int $timeout = null): DataValue
Parameters
$node
NodeId required
The address-space node to read. Build one with NodeId::numeric(), NodeId::string() or NodeId::guid().
$timeout
?int optional default null
Per-call timeout in milliseconds. null falls back to the session-level default; 0 disables the watchdog entirely.

Code tabs

Switch between equivalent snippets in different languages, runtimes, or package managers. Open the first tab by default; use Tab to focus, Enter to switch.

$client = ClientBuilder::create()
    ->withSecurity(SecurityPolicy::Basic256Sha256)
    ->connect('opc.tcp://plc.local:4840');
composer require php-opcua/opcua-client \
  --with-all-dependencies
{
  "endpoint": "opc.tcp://plc.local:4840",
  "security": "Basic256Sha256",
  "timeout_ms": 30000
}

Tables

Plain CommonMark tables. The body wrapper styles header rows as monospace eyebrows and uses thin white/5 dividers between body rows — no outer box, just the same engineering rhythm as the rest of the page.

Method Returns Description
read() DataValue Reads a single attribute from the address space.
write() StatusCode Writes a value back to the target node.
browse() array<Reference> Walks the references of a node.
call() OutputArguments Invokes a Method node and returns its output arguments.

Step-by-step

Numbered timeline for guided walkthroughs. Each step gets a violet badge and a short title; the body accepts paragraphs, code blocks, callouts.

  1. 01

    Install the package

    Use Composer to pull the latest stable:

    composer require php-opcua/opcua-client

  2. 02

    Configure security

    Pick a policy from SecurityPolicy and a matching MessageSecurityMode. For local PLCs without TLS, SecurityPolicy::None + None is acceptable.

  3. 03

    Open the channel

    Call connect() with an opc.tcp:// endpoint. The builder returns a ready-to-use Client; the secure channel and session are negotiated lazily on first request.

  4. 04

    Read, write, subscribe

    Issue your service calls. The library multiplexes them on the same channel until you disconnect().

Related links

"See also" cluster — thin glass card with a short link list. Lighter than callouts; pair it with the end of a section.