sensiolabs/consul-php-sdk
PHP SDK for HashiCorp Consul by SensioLabs. Manage services, health checks, KV store and agent/catalog APIs from PHP, with simple client setup and request/response handling for integrating Consul into your applications.
Installation
composer require sensiolabs/consul-php-sdk
Ensure your PHP version (≥8.0) and extensions (curl, json) are compatible.
First Connection
use SensioLabs\Consul\Consul;
$consul = new Consul('http://localhost:8500');
Replace the URL with your Consul server address.
First Use Case: Agent Self-Check
$agent = $consul->getAgent();
$status = $agent->getSelf();
dd($status); // Check service health, node details, etc.
src/SensioLabs/Consul/ directory for core classes (e.g., Consul.php, Agent.php, Catalog.php).tests/ folder for real-world usage examples.$catalog = $consul->getCatalog();
$services = $catalog->getServices(); // List all registered services
$service = $catalog->getService('web'); // Fetch a specific service
$kv = $consul->getKv();
$kv->set('app/config', json_encode(['debug' => true])); // Store config
$value = $kv->get('app/config')->getValue(); // Retrieve config
$health = $consul->getHealth();
$checks = $health->getChecks(); // List all checks
$serviceChecks = $health->getChecksForService('api'); // Filter by service
$session = $consul->getSession();
$session->create('lock-token', 'app-lock', 30); // Create a session (TTL: 30s)
$lock = $session->getLock('lock-token'); // Acquire lock
Dependency Injection (Laravel)
Bind the SDK in AppServiceProvider:
$this->app->singleton(Consul::class, function ($app) {
return new Consul(config('consul.url'));
});
Inject via constructor:
public function __construct(private Consul $consul) {}
Retry Logic for Transient Failures
Use Laravel’s retry helper or a custom decorator:
$retry = 3;
while ($retry--) {
try {
$services = $consul->getCatalog()->getServices();
break;
} catch (\Exception $e) {
if ($retry === 0) throw $e;
sleep(1);
}
}
Async Operations with Queues Offload long-running tasks (e.g., bulk KV writes) to queues:
dispatch(new WriteToConsul($consul, $data))->onQueue('consul');
Environment-Specific Config
Use Laravel’s .env:
CONSUL_URL=http://consul:8500
CONSUL_TOKEN=your-token-if-auth-enabled
Load in config/consul.php:
'url' => env('CONSUL_URL'),
'token' => env('CONSUL_TOKEN'),
Connection Timeouts
$consul = new Consul('http://consul:8500', [
'timeout' => 10.0, // 10 seconds
]);
Token Authentication
403 Forbidden:
$consul = new Consul('http://consul:8500', [
'token' => env('CONSUL_TOKEN'),
]);
CONSUL_HTTP_TOKEN env var if using Laravel’s env().Rate Limiting
use Symfony\Component\Process\Exception\TimeoutException;
try {
$consul->getCatalog()->getServices();
} catch (TimeoutException $e) {
sleep(2 ** $attempt++); // Exponential backoff
retry();
}
Stale Data
?wait=10s for real-time updates:
$services = $consul->getCatalog()->getServices(['wait' => '10s']);
Namespace Collisions
$kv->set('app/v1/config', $data); // Prefix with app version
Enable HTTP Logging
$consul = new Consul('http://consul:8500', [
'logger' => new \Monolog\Logger('consul', [
new \Monolog\Handler\StreamHandler(storage_path('logs/consul.log')),
]),
]);
Validate API Responses
Check for Consul\Exception\ConsulException and inspect raw responses:
try {
$consul->getKv()->get('nonexistent-key');
} catch (ConsulException $e) {
$response = $e->getResponse();
dd($response->getStatusCode(), $response->getBody());
}
Test Locally with Docker Spin up Consul via Docker:
docker run -d --name consul -p 8500:8500 consul
Test interactions with curl first:
curl http://localhost:8500/v1/catalog/services
Custom HTTP Client Override the default Guzzle client for middleware (e.g., retries, auth):
$client = new \GuzzleHttp\Client([
'timeout' => 15,
'headers' => ['User-Agent' => 'MyApp/1.0'],
]);
$consul = new Consul('http://consul:8500', [], $client);
Event Listeners Subscribe to Consul events (e.g., service registration changes) via webhooks or polling:
$events = $consul->getEvents();
$event = $events->getEvents(['type' => 'service']); // Filter by type
Decorators for Metrics Wrap the SDK to track request latency:
class MetricsConsulDecorator implements ConsulInterface {
public function __construct(private Consul $consul) {}
public function getAgent() {
$start = microtime(true);
$agent = $this->consul->getAgent();
$latency = microtime(true) - $start;
// Log $latency to Prometheus/StatsD
return $agent;
}
}
Fallback Mechanisms Implement a fallback to etcd or local cache if Consul is unavailable:
try {
$services = $consul->getCatalog()->getServices();
} catch (\Exception $e) {
$services = cache()->get('consul_fallback_services', []);
}
How can I help you explore Laravel packages today?