Repository navigation
Big Integers
Consul uses Go uint64 for indexes, flags, and some counters. PHP's int is a signed 64-bit integer, so values above
PHP_INT_MAX (9223372036854775807) would overflow. As of v3.1.0, every uint64 field is a
Brick\Math\BigInteger.
Some common examples:
-
CreateIndex,ModifyIndex,LockIndexon most models KV\KVPair::$Flags-
QueryMeta::$LastIndex,QueryOptions::$WaitIndex -
KVPairCAS indexes (ModifyIndexpassed toKV->CAS()/DeleteCAS()) - Raft indexes and terms (
Operator\RaftServer, autopilot health, etc.) -
Event\UserEvent::$LTimeand the return value ofEvent->IDToIndex()
If a field is uint64 in the Go client, it is a BigInteger
here.
Constructors and setters accept any of:
- a non-negative
int - a numeric
string(an optional leading+is allowed) - a
BigInteger
use DCarbone\PHPConsulAPI\KV\KVPair;
new KVPair(Key: 'a', Flags: 42);
new KVPair(Key: 'a', Flags: '18446744073709551615');
new KVPair(Key: 'a', Flags: \Brick\Math\BigInteger::of(42));Strings are validated with BigInteger::parse() (as
recommended for untrusted input) and a maximum of 20 digits.
Anything else throws \InvalidArgumentException:
| Input | Result |
|---|---|
-1 |
-1 is outside the uint64 range |
'18446744073709551616' |
18446744073709551616 is outside the uint64 range |
'1.5', 'abc', ' 5', '0x10'
|
"..." is not a valid uint64 value |
The same conversion is available as a function:
use function DCarbone\PHPConsulAPI\PHPLib\uint64;
$idx = uint64('12345'); // BigIntegerUse the BigInteger API instead of PHP integer operators:
if ($pair->Flags->isEqualTo(42)) { /* ... */ }
if ($qm->LastIndex->isGreaterThan($lastSeen)) { /* ... */ }
$next = $qm->LastIndex->plus(1);
$asStr = (string)$qm->LastIndex;
$asInt = $pair->Flags->toInt(); // throws Brick\Math\Exception\IntegerOverflowException if > PHP_INT_MAX== and === against an int won't work: a BigInteger is an object.
Pass QueryMeta::$LastIndex straight back as WaitIndex for blocking queries. You don't need to convert it:
[$pairs, $qm, $err] = $consul->KV->List(prefix: 'app/');
[$pairs, $qm, $err] = $consul->KV->List(
prefix: 'app/',
opts: new QueryOptions(WaitIndex: $qm->LastIndex, WaitTime: '5m'),
);Responses are always decoded with JSON_BIGINT_AS_STRING, so large numbers reach the models as strings and are
never truncated to floats.
json_encode() writes BigInteger values as strings, because BigInteger::jsonSerialize() returns a string.
Consul's API expects numbers. The library uses encode_json() internally for request bodies, and you can use it too:
use function DCarbone\PHPConsulAPI\PHPLib\encode_json;
json_encode(['f' => $pair->Flags]); // {"f":"18446744073709551615"}
encode_json(['f' => $pair->Flags]); // {"f":18446744073709551615}encode_json(value, flags, depth) accepts the same flags as json_encode() and throws \JsonException on failure.
Code that did arithmetic or comparisons on these fields needs updating:
// before
if ($pair->ModifyIndex > $last) { $last = $pair->ModifyIndex; }
// after
if ($pair->ModifyIndex->isGreaterThan($last)) { $last = $pair->ModifyIndex; }Setters still accept plain ints, so most write-side code is unchanged.