google/cloud-spanner
Idiomatic PHP client for Google Cloud Spanner, a fully managed relational database with global scale, strong transactional consistency, SQL support, and high availability. Install via Composer, authenticate, and run queries; supports gRPC and multiplexed sessions.
Installation:
composer require google/cloud-spanner
Ensure the grpc PHP extension is installed and enabled.
Authentication:
Configure credentials via environment variables (GOOGLE_APPLICATION_CREDENTIALS) or service account JSON file.
Example:
putenv('GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json');
First Query:
use Google\Cloud\Spanner\SpannerClient;
$spanner = new SpannerClient();
$db = $spanner->instance('your-instance-id')->database('your-database-id');
$result = $db->execute('SELECT * FROM Users WHERE id = @id', [
'parameters' => ['id' => 123]
]);
foreach ($result->rows() as $row) {
print_r($row);
}
execute() for reads and runUpdate() for writes.beginTransaction() for atomicity.executeDdl() for schema changes.// Parameterized query (recommended)
$result = $db->execute('SELECT * FROM Users WHERE email = @email', [
'parameters' => ['email' => 'user@example.com']
]);
// Batch queries
$batch = $db->createBatchDmlStatement();
$batch->insert('Users', ['id' => 1, 'name' => 'John']);
$batch->update('Users', ['name' => 'Jane'], ['id' => 1]);
$db->executeBatchDml($batch);
$transaction = $db->beginTransaction();
try {
$transaction->runUpdate('UPDATE Accounts SET balance = balance - @amount WHERE id = @id', [
'parameters' => ['amount' => 100, 'id' => 1]
]);
$transaction->commit();
} catch (\Exception $e) {
$transaction->rollback();
throw $e;
}
$db->executeDdl('
CREATE TABLE IF NOT EXISTS Users (
id INT64 NOT NULL,
name STRING(100),
email STRING(255)
) PRIMARY KEY (id)
');
$batch = $db->createBatchDmlStatement();
$batch->insert('Orders', ['id' => 1, 'user_id' => 1, 'amount' => 100]);
$batch->insert('Orders', ['id' => 2, 'user_id' => 2, 'amount' => 200]);
$db->executeBatchDml($batch);
AppServiceProvider:
$this->app->singleton(SpannerClient::class, function ($app) {
return new SpannerClient();
});
executeAsync() for non-blocking queries (requires grpc async support).gRPC Extension:
Class 'Google\Cloud\Spanner\SpannerClient' not found or Failed to load gRPC extension.grpc extension and restart PHP-FPM/Apache.
pecl install grpc
sudo systemctl restart php-fpm
Session Expiry:
Session expired after 7 days of inactivity.$db->session()->refresh();
Parameter Binding:
Invalid parameter type for complex objects.Multiplexed Sessions:
cacheItemPool (e.g., Redis) for shared caching:
$spanner = new SpannerClient([
'cacheItemPool' => new RedisCacheItemPool(Redis::connection())
]);
$spanner = new SpannerClient([
'logging' => [
'level' => \Google\Cloud\Core\Logging\LogLevel::DEBUG,
'handler' => new \Monolog\Handler\StreamHandler('spanner.log', \Monolog\Logger::DEBUG)
]
]);
EXPLAIN to analyze query performance:
$explain = $db->execute('EXPLAIN SELECT * FROM Users');
Custom Value Mappers: Override default type mapping (e.g., for custom JSON fields):
$db->setValueMapper(new class extends \Google\Cloud\Spanner\ValueMapper {
public function mapValue($value, $type) {
if ($type === 'JSON') {
return json_decode($value, true);
}
return parent::mapValue($value, $type);
}
});
Middleware: Add request/response middleware for logging or metrics:
$spanner = new SpannerClient([
'middleware' => [
new class implements \Google\Cloud\Core\Middleware\MiddlewareInterface {
public function handle($request, callable $next) {
// Pre-process request
$response = $next($request);
// Post-process response
return $response;
}
}
]
]);
Locking Strategies: Customize session locking for high-concurrency scenarios:
$lock = new \Google\Cloud\Core\Lock\RedisLock(Redis::connection());
$db = $spanner->instance('instance')->database('db', ['lock' => $lock]);
How can I help you explore Laravel packages today?