Skip to content

Query and Write Options

Daniel Carbone edited this page Nov 6, 2026 · 1 revision

Query and Write Options

Most client methods accept an optional trailing options argument, the equivalent of the Go client's *QueryOptions / *WriteOptions. Read endpoints take DCarbone\PHPConsulAPI\QueryOptions and write endpoints take DCarbone\PHPConsulAPI\WriteOptions. Options override the Config defaults for that request only.

use DCarbone\PHPConsulAPI\QueryOptions;
use DCarbone\PHPConsulAPI\WriteOptions;

[$nodes, $qm, $err] = $consul->Catalog->Nodes(opts: new QueryOptions(Datacenter: 'dc2', AllowStale: true));

[$wm, $err] = $consul->KV->Put(p: $pair, opts: new WriteOptions(Token: $otherToken));

QueryOptions

Parameter Type Sent as Description
Namespace string ?ns= Namespace (Enterprise)
Datacenter string ?dc= Target datacenter
AllowStale bool ?stale Allow any server to answer (consistency modes)
RequireConsistent bool ?consistent Force a consistent read via the leader
UseCache bool ?cached Use the agent cache (agent caching); ignored if RequireConsistent
MaxAge duration Cache-Control: max-age Max acceptable cache age (with UseCache)
StaleIfError duration Cache-Control: stale-if-error Serve stale cache on error (with UseCache)
WaitIndex int|string|BigInteger ?index= Blocking query index
WaitHash string ?hash= Hash-based blocking query
WaitTime duration ?wait= Max blocking time
Token string X-Consul-Token ACL token
Near string ?near= Sort results by RTT from this node (_agent for the local agent)
Filter string ?filter= Filter expression
NodeMeta array<string,string> ?node-meta=k:v Filter by node metadata
RelayFactor int ?relay-factor= Gossip relay factor (Agent/Event)
LocalOnly bool ?local-only=true Only query the local agent (Agent->Members, etc.)
Connect bool ?connect=true Connect-capable instances only
Timeout duration Guzzle timeout Client-side request timeout
Pretty bool ?pretty Pretty-print the response JSON

WriteOptions

Parameter Type Sent as Description
Namespace string ?ns= Namespace (Enterprise)
Datacenter string ?dc= Target datacenter
Token string X-Consul-Token ACL token
RelayFactor int ?relay-factor= Gossip relay factor
Timeout duration Guzzle timeout Client-side request timeout

"duration" means anything accepted by Time::Duration(): '30s', an int of nanoseconds, a \DateInterval, or a Time\Duration. See Durations and Time.

Timeout is converted to whole seconds. Values under one second are ignored.

Blocking queries

Blocking queries wait until the result changes or WaitTime elapses. Pass the previous QueryMeta::$LastIndex as WaitIndex:

use DCarbone\PHPConsulAPI\QueryOptions;

$index = 0;
while (true) {
    [$entries, $qm, $err] = $consul->Health->Service(
        service: 'web',
        passingOnly: true,
        opts: new QueryOptions(WaitIndex: $index, WaitTime: '5m'),
    );
    if (null !== $err) {
        sleep(5);
        continue;
    }

    // Consul docs: reset if the index goes backwards
    if ($qm->LastIndex->isLessThan($index)) {
        $index = 0;
        continue;
    }
    if ($qm->LastIndex->isEqualTo($index)) {
        continue; // timed out without a change
    }
    $index = $qm->LastIndex;

    reconfigure($entries);
}

Make sure the HTTP client timeout is longer than WaitTime. Consul adds up to WaitTime / 16 of jitter.

Endpoints that use content hashes instead of indexes populate $qm->LastContentHash. Pass it back as WaitHash.

Filtering

[$services, $err] = $consul->Agent->ServicesWithFilter(filter: 'Service == "web" and "primary" in Tags');

[$nodes, $qm, $err] = $consul->Catalog->Nodes(
    opts: new QueryOptions(Filter: 'Meta.env == "prod"'),
);

Consistency and caching

// Any server may answer; check $qm->LastContact and $qm->KnownLeader for staleness
new QueryOptions(AllowStale: true);

// Strongly consistent read
new QueryOptions(RequireConsistent: true);

// Agent cache; check $qm->CacheHit and $qm->CacheAge
new QueryOptions(UseCache: true, MaxAge: '30s', StaleIfError: '5m');

Clone this wiki locally