php-opcua/laravel-opcua

Laravel integration for OPC UA client with optional session manager support

Maintainers

Package info

github.com/php-opcua/laravel-opcua

pkg:composer/php-opcua/laravel-opcua

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v4.0.0 2026-03-30 10:47 UTC

This package is auto-updated.

Last update: 2026-03-30 10:52:19 UTC


README

OPC UA Laravel Client

Tests Coverage Latest Version PHP Version License

Laravel integration for OPC UA built on opcua-php-client and opcua-php-client-session-manager. Connect your Laravel app to PLCs, SCADA systems, sensors, and IoT devices with a familiar developer experience: a Facade, .env-based configuration, named connections (like config/database.php), and an Artisan command for the optional session manager daemon.

What you get:

  • FacadeOpcua::read('i=2259') with full IDE autocompletion
  • Named connections — define multiple OPC UA servers and switch between them, just like database connections
  • Transparent session management — when the daemon is running, connections persist across HTTP requests; when it's not, direct per-request connections with zero code changes
  • Laravel-native logging and caching — your log channel and cache store are automatically injected into every OPC UA client
  • All OPC UA operations — browse, read, write, method calls, subscriptions, events, history, path resolution, type discovery
  • PSR-14 events — 47 dispatched events covering every OPC UA operation for observability and extensibility
  • Trust store — certificate trust management with configurable policies and auto-accept modes
  • Write auto-detection — omit the type parameter and let the client detect the correct OPC UA type automatically

Note: This package wraps the full opcua-php-client API with Laravel conventions. For the underlying protocol details, types, and advanced features, see the client documentation.

Quick Start

composer require php-opcua/laravel-opcua
OPCUA_ENDPOINT=opc.tcp://192.168.1.100:4840
use PhpOpcua\LaravelOpcua\Facades\Opcua;

$client = Opcua::connect();

$value = $client->read('i=2259');
echo $value->getValue(); // 0 = Running

$client->disconnect();

That's it. Facade, .env, connect, read. Everything else is optional.

See It in Action

Browse the address space

$client = Opcua::connect();

$refs = $client->browse('i=85'); // Objects folder
foreach ($refs as $ref) {
    echo "{$ref->displayName} ({$ref->nodeId})\n";
}

$client->disconnect();

Read multiple values with fluent builder

$client = Opcua::connect();

$results = $client->readMulti()
    ->node('i=2259')->value()
    ->node('ns=2;i=1001')->displayName()
    ->execute();

foreach ($results as $dv) {
    echo $dv->getValue() . "\n";
}

$client->disconnect();

Write to a PLC

use PhpOpcua\Client\Types\BuiltinType;

$client = Opcua::connect();
$client->write('ns=2;i=1001', 42, BuiltinType::Int32);

// Or let the client auto-detect the type
$client->write('ns=2;i=1001', 42);

$client->disconnect();

Call a method on the server

use PhpOpcua\Client\Types\Variant;
use PhpOpcua\Client\Types\BuiltinType;

$client = Opcua::connect();

$result = $client->call(
    'i=2253',   // Server object
    'i=11492',  // Method
    [new Variant(BuiltinType::UInt32, 1)],
);

echo $result->statusCode;               // 0
echo $result->outputArguments[0]->value; // [1001, 1002, ...]

$client->disconnect();

Subscribe to data changes

$client = Opcua::connect();

$sub = $client->createSubscription(publishingInterval: 500.0);
$client->createMonitoredItems($sub->subscriptionId, [
    ['nodeId' => 'ns=2;i=1001'],
]);

$response = $client->publish();
foreach ($response->notifications as $notif) {
    echo $notif['dataValue']->getValue() . "\n";
}

$client->deleteSubscription($sub->subscriptionId);
$client->disconnect();

Switch connections

// Named connection from config
$client = Opcua::connect('plc-line-1');
$value = $client->read('ns=2;i=1001');
Opcua::disconnect('plc-line-1');

// Ad-hoc connection at runtime
$client = Opcua::connectTo('opc.tcp://10.0.0.50:4840', [
    'username' => 'operator',
    'password' => 'secret',
], as: 'temp-plc');

Opcua::disconnectAll();

Test without a real server

use PhpOpcua\Client\Testing\MockClient;
use PhpOpcua\Client\Types\DataValue;

$mock = MockClient::create()
    ->onRead('i=2259', fn() => DataValue::ofInt32(0));

// Inject into OpcuaManager via DI or reflection
$value = $mock->read('i=2259');
echo $value->getValue(); // 0
echo $mock->callCount('read'); // 1

Features

Feature What it does
Facade Opcua::read(), Opcua::browse(), etc. with full PHPDoc for IDE autocompletion
Named Connections Define multiple servers in config/opcua.php, switch with Opcua::connection('plc-2')
Ad-hoc Connections Opcua::connectTo('opc.tcp://...') for endpoints not in config
Session Manager Artisan command php artisan opcua:session for daemon-based session persistence
Transparent Fallback Daemon available? ManagedClient. Not available? Direct Client. Zero code changes
String NodeIds 'i=2259', 'ns=2;s=MyNode' everywhere a NodeId is accepted
Fluent Builder API readMulti(), writeMulti(), createMonitoredItems(), translateBrowsePaths() chain
PSR-3 Logging Laravel's log channel injected automatically via config
PSR-14 Events 47 dispatched events covering every OPC UA operation for observability and extensibility
PSR-16 Caching Laravel's cache store injected automatically. Per-call useCache on browse ops
Write Auto-Detection write('ns=2;i=1001', 42) — omit the type and the client detects it automatically
Read Metadata Cache Cached node metadata avoids redundant reads; refresh on demand with read($nodeId, refresh: true)
Trust Store FileTrustStore with configurable TrustPolicy, auto-accept modes, and certificate management
Type Discovery discoverDataTypes() auto-detects custom server structures
Subscription Management createMonitoredItems(), modifyMonitoredItems(), setTriggering(), transferSubscriptions()
MockClient Test without a server — register handlers, assert calls
Timeout & Retry Per-connection timeout, auto_retry via config or fluent API
Auto-Batching readMulti/writeMulti transparently split when exceeding server limits
Recursive Browse browseAll(), browseRecursive() with depth control and cycle detection
Path Resolution resolveNodeId('/Objects/Server/ServerStatus')
Security 6 policies, 3 auth modes, auto-generated certs, certificate trust management
History Read Raw, processed, and at-time historical queries
Typed Returns All service responses return public readonly DTOs

Documentation

# Document Covers
01 Introduction Overview, requirements, architecture, quick start
02 Installation & Configuration Composer, config file, .env, connections, session manager
03 Usage Reading, writing, browsing, methods, subscriptions, history
04 Connections Named, ad-hoc, switching, disconnect, dependency injection
05 Session Manager Daemon, Artisan command, Supervisor, architecture
06 Logging & Caching PSR-3/PSR-16, Laravel integration, per-call cache control
07 Security Policies, modes, certificates, authentication
08 Testing MockClient, DataValue factories, unit and integration tests
09 Examples Complete code examples for all features

Testing

80+ unit tests with 99%+ code coverage. Integration tests run against opcua-test-server-suite Docker containers in both direct and managed (daemon) modes.

./vendor/bin/pest tests/Unit/                              # unit only
./vendor/bin/pest tests/Integration/ --group=integration   # integration only
./vendor/bin/pest                                          # everything

Ecosystem

Package Description
opcua-php-client Pure PHP OPC UA client — the core protocol implementation
opcua-php-client-session-manager Daemon-based session persistence across PHP requests
opcua-laravel-client Laravel integration (this package)
opcua-test-server-suite Docker-based OPC UA test servers for integration testing
opcua-php-events PSR-14 event definitions for OPC UA operations

Contributing

Contributions welcome — see CONTRIBUTING.md.

Changelog

See CHANGELOG.md.

License

MIT