Architecture
Getting Started
Introduction ConnectionCore
Browsing Reading-writing Method-call Subscriptions History-readReference
Types Error-handling Security Architecture Extension-object-codecs Testing Events Trust-storeArchitecture
Project Structure
src/
├── ClientBuilder.php # Builder / entry point
├── ClientBuilderInterface.php # Builder interface
├── Client.php # Connected client (operations)
├── OpcUaClientInterface.php # Public API interface
│
├── ClientBuilder/ # Builder traits (configuration)
│ ├── ManagesAutoRetryTrait.php # Auto-retry configuration
│ ├── ManagesBatchingTrait.php # Batch size configuration
│ ├── ManagesBrowseDepthTrait.php # Recursive browse depth config
│ ├── ManagesCacheTrait.php # PSR-16 cache configuration
│ ├── ManagesEventDispatcherTrait.php # PSR-14 event dispatcher config
│ ├── ManagesReadWriteConfigTrait.php # Read/write config (auto-detect, metadata cache)
│ ├── ManagesTimeoutTrait.php # Timeout configuration
│ └── ManagesTrustStoreTrait.php # Trust store configuration
│
├── Client/ # Connected client traits (operations, runtime)
│ ├── ManagesBatchingRuntimeTrait.php # Runtime batch splitting
│ ├── ManagesBrowseTrait.php # Browse operations
│ ├── ManagesCacheRuntimeTrait.php # Runtime cache operations
│ ├── ManagesConnectionTrait.php # Connect / disconnect / reconnect
│ ├── ManagesEventDispatchTrait.php # Runtime event dispatching
│ ├── ManagesHandshakeTrait.php # HEL/ACK handshake
│ ├── ManagesHistoryTrait.php # History read operations
│ ├── ManagesReadWriteTrait.php # Read / write operations
│ ├── ManagesSecureChannelTrait.php # Secure channel lifecycle
│ ├── ManagesSessionTrait.php # Session create / activate
│ ├── ManagesSubscriptionsTrait.php # Subscriptions and monitored items
│ ├── ManagesTranslateBrowsePathTrait.php # Browse path translation
│ ├── ManagesTrustStoreRuntimeTrait.php # Runtime trust store validation
│ └── ManagesTypeDiscoveryTrait.php # Automatic DataType discovery
│
├── Transport/
│ └── TcpTransport.php # TCP socket I/O
│
├── Encoding/
│ ├── BinaryEncoder.php # Serialization (write)
│ ├── BinaryDecoder.php # Deserialization (read)
│ ├── ExtensionObjectCodec.php # Interface for custom type codecs
│ ├── DynamicCodec.php # Auto-generated codec from StructureDefinition
│ ├── DataTypeMapping.php # Maps DataType NodeIds to BuiltinTypes
│ └── StructureDefinitionParser.php # Parses DataTypeDefinition attributes
│
├── Protocol/
│ ├── AbstractProtocolService.php # Shared encode/decode base class
│ ├── ServiceTypeId.php # Named constants for OPC UA service NodeIds
│ ├── MessageHeader.php # OPC UA message framing
│ ├── HelloMessage.php # HEL message
│ ├── AcknowledgeMessage.php # ACK message
│ ├── SecureChannelRequest.php # OPN request
│ ├── SecureChannelResponse.php # OPN response
│ ├── SessionService.php # CreateSession / ActivateSession
│ ├── BrowseService.php # Browse / BrowseNext
│ ├── ReadService.php # Read
│ ├── WriteService.php # Write
│ ├── CallService.php # Call (method invocation)
│ ├── GetEndpointsService.php # GetEndpoints
│ ├── SubscriptionService.php # Create / Modify / Delete Subscription
│ ├── MonitoredItemService.php # Create / Delete MonitoredItems
│ ├── PublishService.php # Publish (notifications)
│ ├── HistoryReadService.php # HistoryRead (raw / processed / attime)
│ └── TranslateBrowsePathService.php # TranslateBrowsePathsToNodeIds
│
├── Security/
│ ├── SecurityPolicy.php # Security policy enum + algorithm config
│ ├── SecurityMode.php # Security mode enum
│ ├── SecureChannel.php # Secure channel lifecycle
│ ├── MessageSecurity.php # Cryptographic operations
│ └── CertificateManager.php # Certificate loading & utilities
│
├── Types/
│ ├── BuiltinType.php # OPC UA type enum
│ ├── NodeClass.php # Node class enum
│ ├── NodeId.php # Node identifier
│ ├── Variant.php # Typed value container
│ ├── DataValue.php # Value + status + timestamps
│ ├── QualifiedName.php # Namespace-qualified name
│ ├── LocalizedText.php # Locale-aware text
│ ├── ReferenceDescription.php # Browse result item
│ ├── EndpointDescription.php # Server endpoint info
│ ├── UserTokenPolicy.php # Authentication policy
│ ├── StatusCode.php # Status code constants & helpers
│ ├── AttributeId.php # Attribute ID constants
│ ├── ConnectionState.php # Connection state enum
│ ├── BrowseDirection.php # Browse direction enum
│ ├── BrowseNode.php # Recursive browse tree node DTO
│ ├── BrowseResultSet.php # Browse with continuation result DTO
│ ├── BrowsePathResult.php # Translate browse path result DTO
│ ├── BrowsePathTarget.php # Single resolved browse path target DTO
│ ├── CallResult.php # Method call result DTO
│ ├── SubscriptionResult.php # Create subscription result DTO
│ ├── MonitoredItemResult.php # Create monitored item result DTO
│ ├── PublishResult.php # Publish response result DTO
│ ├── ExtensionObject.php # Typed ExtensionObject DTO (raw or decoded)
│ ├── StructureField.php # Field descriptor for structure definitions
│ └── StructureDefinition.php # Structure layout for dynamic codecs
│
├── Builder/ # Fluent builders for multi-operations
│ ├── ReadMultiBuilder.php # Builder for readMulti()
│ ├── WriteMultiBuilder.php # Builder for writeMulti()
│ ├── MonitoredItemsBuilder.php # Builder for createMonitoredItems()
│ └── TranslateBrowsePathsBuilder.php # Builder for translateBrowsePaths()
│
├── Event/
│ ├── NullEventDispatcher.php # No-op PSR-14 dispatcher (default)
│ ├── Client*.php # Connection lifecycle events (6)
│ ├── Session*.php # Session events (3)
│ ├── Subscription*.php # Subscription events (4)
│ ├── MonitoredItem*.php # Monitored item events (2)
│ ├── DataChangeReceived.php # Data change notification event
│ ├── EventNotificationReceived.php # Event notification event
│ ├── PublishResponseReceived.php # Publish response event
│ ├── SubscriptionKeepAlive.php # Keep-alive event
│ ├── Alarm*.php # Alarm events (8)
│ ├── NodeValue*.php # Read/Write events (3)
│ ├── NodeBrowsed.php # Browse event
│ ├── SecureChannel*.php # Secure channel events (2)
│ ├── DataTypesDiscovered.php # Type discovery event
│ ├── Cache*.php # Cache hit/miss events (2)
│ ├── Retry*.php # Retry events (2)
│ └── ServerCertificate*.php # Trust store events (5)
│
│ # CLI tool moved to separate package: php-opcua/opcua-cli
│
├── TrustStore/
│ ├── TrustStoreInterface.php # Trust store contract
│ ├── FileTrustStore.php # File-based implementation (~/.opcua/)
│ ├── TrustPolicy.php # Validation policy enum
│ └── TrustResult.php # Validation result DTO
│
├── Cache/
│ ├── InMemoryCache.php # PSR-16 in-memory cache
│ └── FileCache.php # PSR-16 file-based cache
│
├── Repository/
│ └── ExtensionObjectRepository.php # Per-client codec registry
│
├── Testing/
│ └── MockClient.php # In-memory test double (no TCP)
│
└── Exception/
├── OpcUaException.php # Base exception
├── ConfigurationException.php # Config errors
├── ConnectionException.php # TCP errors
├── EncodingException.php # Binary codec errors
├── InvalidNodeIdException.php # Malformed NodeId errors
├── ProtocolException.php # Protocol violations
├── SecurityException.php # Crypto errors
├── UntrustedCertificateException.php # Untrusted server cert (extends SecurityException)
└── ServiceException.php # Server errors (with status code)Layers
┌─────────────────────────────────┐
│ ClientBuilder │ Configuration & entry point
│ (+ ClientBuilder/*Trait.php) │ Config traits (cache, events, etc.)
├─────────────────────────────────┤
│ Client │ Connected client (operations)
│ (+ Client/*Trait.php) │ Runtime traits (browse, read, etc.)
├─────────────────────────────────┤
│ Protocol/*Service │ OPC UA service encoding/decoding
├──────────────┬──────────────────┤
│ BinaryEncoder│ BinaryDecoder │ Binary serialization
├──────────────┴──────────────────┤
│ SecureChannel │ Message-level security
├─────────────────────────────────┤
│ MessageSecurity │ Cryptographic operations
│ CertificateManager │ Certificate handling
├─────────────────────────────────┤
│ TcpTransport │ TCP socket I/O
└─────────────────────────────────┘ClientBuilder is the entry point for configuration. Calling connect() returns a Client for operations. Each layer only talks to the one directly below it.
Dependencies
The library has three Composer dependencies (all interface-only, zero runtime code):
psr/log— PSR-3 logger interface. The client accepts anyPsr\Log\LoggerInterfaceimplementation (Monolog, Laravel, etc.) and defaults toNullLoggerwhen none is provided.psr/simple-cache— PSR-16 cache interface. The client usesCacheInterfacefor browse result caching. Ships withInMemoryCache(default) andFileCache. Any PSR-16 compatible driver (Laravel Cache, Symfony Cache, etc.) can be plugged in.psr/event-dispatcher— PSR-14 event dispatcher interface. The client dispatches 47 granular events at lifecycle points. Defaults toNullEventDispatcher(zero overhead). Any PSR-14 compatible dispatcher (Laravel, Symfony, etc.) can be injected.
The only PHP extension required is ext-openssl.
Service Pattern
All protocol services follow the same structure:
- Each wraps a
SessionServiceinstance - Separate
encodeanddecodemethods per operation - Both secure and non-secure code paths
- Inner body construction is factored out for reuse
encodeFooRequest()
├── (no security) → write headers + body → wrapInMessage()
└── (security) → write body → secureChannel->buildMessage()
decodeFooResponse()
└── read headers → readResponseHeader() → parse result fieldsAdding a new OPC UA service means writing one class with encode*Request() and decode*Response() methods. The security, framing, and transport layers handle everything else.
Message Format
Non-Secure
┌──────────┬─────────────┬──────────┬───────────┬─────────────┐
│ MSG/F │ MessageSize │ ChannelId│ TokenId │ Sequence │
│ (3+1 B) │ (4 B) │ (4 B) │ (4 B) │ Num + ReqId │
├──────────┴─────────────┴──────────┴───────────┴─────────────┤
│ Service Body │
│ (TypeId + RequestHeader + Service-specific fields) │
└──────────────────────────────────────────────────────────────┘Secure
┌──────────┬─────────────┬──────────┐
│ MSG/F │ MessageSize │ ChannelId│
├──────────┴─────────────┴──────────┤
│ TokenId │ SequenceNum │ RequestId │
├─────────┴─────────────┴───────────┤
│ Encrypted Body │ ← AES-CBC
│ (TypeId + Headers + Fields) │
│ + Padding + PaddingByte │
├───────────────────────────────────┤
│ HMAC Signature │ ← HMAC-SHA1/SHA256
└───────────────────────────────────┘Binary Encoding Notes
The library implements OPC UA Binary encoding (Part 6 of the spec):
- Little-endian byte order for all integers
- Length-prefixed strings --
Int32length + UTF-8 bytes,-1for null - NodeId compact encoding -- TwoByte / FourByte / Numeric / String / Guid / Opaque, chosen automatically based on namespace and identifier
- Variant -- type byte with optional array dimension flag
- DataValue -- bitmask header indicating which optional fields are present (value, status, timestamps)
- DateTime -- 100-nanosecond intervals since 1601-01-01 UTC