Builder API
Every method on ClientBuilder, grouped by what it configures. The builder is the only configuration surface — call it before connect(), never after.
PhpOpcua\Client\ClientBuilder is the entry point for every
configuration knob. Build it, set what you need, call connect(). The
returned Client is frozen — to change parameters, build a new one.
use PhpOpcua\Client\ClientBuilder;
$client = ClientBuilder::create()
->setSecurityPolicy(SecurityPolicy::Basic256Sha256)
->setSecurityMode(SecurityMode::SignAndEncrypt)
->setClientCertificate('/etc/opcua/client.pem', '/etc/opcua/client.key')
->setUserCredentials('integrations', getenv('OPCUA_PASSWORD'))
->setTrustStore(new FileTrustStore('/var/lib/opcua/trust'))
->setTrustPolicy(TrustPolicy::FingerprintAndExpiry)
->setLogger($logger)
->setEventDispatcher($dispatcher)
->setTimeout(10.0)
->setAutoRetry(3)
->connect('opc.tcp://plc.local:4840');
Construction
ClientBuilder::create(): self
Canonical entry. Equivalent to new ClientBuilder() but reads like
the rest of the fluent chain.
Transport — security & authentication
setSecurityPolicy(SecurityPolicy \$policy): self
setSecurityMode(SecurityMode \$mode): self
setClientCertificate(string \$certPath, string \$keyPath, ?string \$caCertPath = null): self
setUserCredentials(string \$username, string \$password): self
setUserCertificate(string \$certPath, string \$keyPath): self
See Security · Policies and Security · Authentication.
Trust store
setTrustStore(?TrustStoreInterface \$trustStore): self
setTrustPolicy(?TrustPolicy \$policy): self
autoAccept(bool \$enabled = true, bool \$force = false): self
Defaults: no trust store, no trust policy (null = accept anything),
auto-accept disabled. See Security · Trust store.
Cache
setCache(?CacheInterface \$cache): self
setCacheCodec(?CacheCodecInterface \$codec): self
setReadMetadataCache(bool \$enabled): self
Defaults: InMemoryCache(300), WireCacheCodec (no unserialize()),
metadata cache off. See Observability · Caching
and Security · Cache path hardening.
Network behaviour
setTimeout(float \$timeout): self
setAutoRetry(int \$maxRetries): self
setBatchSize(int \$batchSize): self
Defaults: timeout 5.0 s, retry 0, batch size auto-detected from
the server's MaxNodesPerRead / MaxNodesPerWrite operational limits.
See Connection · Timeouts and retry.
Browsing
setDefaultBrowseMaxDepth(int \$maxDepth): self
Default: 4. Bounds browseRecursive() when called with
$maxDepth = null. See Operations · Browsing.
Reading & writing
setAutoDetectWriteType(bool \$enabled): self
loadGeneratedTypes(GeneratedTypeRegistrar \$registrar): self
Defaults: write-type auto-detect on, no generated type registrar.
loadGeneratedTypes() is the hook for code generated by external
tooling that wants to pre-register codecs and enum mappings at build
time. See Operations · Writing values
and Extensibility · Type discovery.
Observability
setLogger(LoggerInterface \$logger): self
setEventDispatcher(EventDispatcherInterface \$dispatcher): self
Defaults: NullLogger, NullEventDispatcher. Both are real, no-op
implementations — zero overhead when not wired. See
Observability · Logging and
Observability · Events.
Modules
addModule(ServiceModule \$module): static
replaceModule(string \$moduleClass, ServiceModule \$replacement): static
Defaults: the eight built-in modules (ReadWriteModule,
BrowseModule, SubscriptionModule, HistoryModule,
NodeManagementModule, TranslateBrowsePathModule,
ServerInfoModule, TypeDiscoveryModule). See Extensibility ·
Modules and Extensibility · Replacing
modules.
Extension object repository
getExtensionObjectRepository(): ExtensionObjectRepository
Returns the repository so codecs can be registered on it before
connect():
$builder = ClientBuilder::create();
$builder->getExtensionObjectRepository()
->register(NodeId::numeric(2, 5001), Vector3DCodec::class);
$client = $builder->connect('opc.tcp://plc.local:4840');
The same repository is exposed on the resulting Client, so codecs
can be added after connect too — but the cleaner pattern is to
register up front.
Terminal call
connect(string \$endpointUrl): Client
The only call that leaves the builder. Returns a Client in
ConnectionState::Connected. After connect(), do not call any
setter on the builder — the builder is no longer the source of truth.
Reading current configuration
Symmetric getX() accessors exist for the configuration the
ClientKernelInterface exposes — useful in module code, testing, and
diagnostic logs. See Client API · Configuration
accessors.
Builder lifecycle
new ClientBuilder() ← all defaults applied
│
├── setX() … setY() … ← any order, any number of times
│
▼
connect($url) ← single terminal call
│
▼
Client (frozen configuration)
The builder is not designed to be reused across connect() calls.
After a successful connect(), the next builder operation should be a
new ClientBuilder::create() — re-using the same builder for a second
connect is undefined behaviour.