Installation
composer require, vendor:publish, set OPCUA_ENDPOINT in .env, done. The package auto-registers — no service provider to add by hand.
php-opcua/laravel-opcua installs through Composer with Laravel's
package auto-discovery. No service-provider registration, no
facade alias to add manually — the composer.json extra.laravel
block does both.
Requirements
| Component | Version |
|---|---|
| PHP | ≥ 8.2 |
| Laravel | 11.x, 12.x, or 13.x |
ext-openssl |
Required (transitively from opcua-client) |
Tested on every Laravel version listed; CI runs the test suite against all three on PHP 8.2 / 8.3 / 8.4 / 8.5.
Install
composer require php-opcua/laravel-opcua
Composer pulls in:
php-opcua/opcua-client— the OPC UA stackphp-opcua/opcua-session-manager— the optional daemonpsr/log,psr/event-dispatcher,psr/simple-cache— the interfaces Laravel implements
Laravel auto-discovery wires up the service provider and the
Opcua facade. No further changes to config/app.php or
bootstrap/providers.php.
Publish the configuration
php artisan vendor:publish --tag=opcua-config
This copies config/opcua.php into your application. Edit it as
needed; see Configuration · The config file
for the full walkthrough.
You can skip the publish step if the defaults work for you — the package merges its config from inside the vendor directory.
Configure the endpoint
Edit .env and set at minimum the OPC UA endpoint URL:
OPCUA_ENDPOINT=opc.tcp://plc.local:4840
Everything else has sensible defaults:
| Variable | Default | Effect |
|---|---|---|
OPCUA_ENDPOINT |
opc.tcp://localhost:4840 |
The OPC UA server to connect to |
OPCUA_SECURITY_POLICY |
None |
Channel security policy |
OPCUA_SECURITY_MODE |
None |
Channel security mode |
OPCUA_USERNAME / OPCUA_PASSWORD |
unset | Anonymous session if both empty |
OPCUA_TIMEOUT |
5.0 |
Per-call timeout |
OPCUA_SESSION_MANAGER_ENABLED |
true |
Use the daemon when reachable |
See Environment variables for the full table.
Verify
In Tinker:
php artisan tinker
>>> use PhpOpcua\LaravelOpcua\Facades\Opcua;
>>> Opcua::isSessionManagerRunning();
=> false // expected when daemon isn't started
>>> Opcua::read('i=2261')->getValue(); // server product name (well-known)
=> "open62541 OPC UA Server" // or whichever server you targeted
If the read returns a value, the package is wired correctly and
your .env matches a reachable server.
If the read raises an exception, see the error and consult:
ServiceExceptionwithgetStatusCode()→StatusCode::getName($code) === 'BadNodeIdUnknown'— the server is up buti=2261isn't there. Rare; almost every server publishes this. (Note:BadNodeIdUnknownis the name of the status code, not an exception class — the exception raised isServiceException.)ConnectionException— host unreachable, port wrong, server down. Fix the URL.UntrustedCertificateException— server is secured; see Security · Trust store.
Optional — start the session manager
For request-driven applications (Laravel HTTP handlers, queue workers), the session-manager daemon keeps OPC UA sessions alive across requests. Without it, every request opens a new session.
Start in the foreground for development:
php artisan opcua:session
Leave it running while you develop. In production, supervise with systemd or Laravel Sail / Octane / Horizon's process manager — see Session manager · Production supervisor.
Optional — install companion-spec types
If your servers implement OPC Foundation companion specs (Machinery, Robotics, BACnet, MachineTool, …), pull the pre-generated PHP types:
composer require php-opcua/opcua-client-nodeset
51 companion specs come pre-generated. Load specific ones via the OPC UA client builder — see Recipes · Using companion specs.
What now
Three readable next steps:
- Quick start —
Opcua::read()in a Laravel controller, three minutes. - How laravel-opcua fits — the mental model. Read this once; it pays off forever.
- The config file — every knob, one page.