This package provides interface contracts for database connection management with read/write splitting support. Implementations can be used in any PHP environment, including long-running processes like RoadRunner, Swoole, or FrankenPHP.
Important: This is a contract-only package. It defines interfaces but does not provide implementations.
- Read/Write Splitting: Separate connections for primary (write) and replica (read) databases
- Connection Management: Handle connection lifecycle, validation, and reconnection
- Automatic Load Balancing: Distribute read operations across multiple replicas
- Failover Support: Automatic failover when replicas become unhealthy
- Statistics Tracking: Monitor read/write counts and failover events
- PHP >= 8.2
- ext-pdo
composer require jardisport/dbconnectionCore interface for database connections with support for:
- PDO instance access (
pdo()) - Connection validation (
isConnected()) - Connection lifecycle management (
disconnect(),reconnect()) - Transaction management (
beginTransaction(),commit(),rollback(),inTransaction()) - Metadata access (
getDriverName(),getDatabaseName()) - Default PDO options constant (
DEFAULT_OPTIONS)
Interface for read/write splitting in database replication setups:
getWriter(): Returns aDbConnectionInterfacefor write operations (primary database)getReader(): Returns aDbConnectionInterfacefor read operations (replica database)getReaders(): Returns all configured reader connections asarray<DbConnectionInterface>getReaderCount(): Returns the number of configured readers (minimum 1, as writer is used as fallback)getStats(): Returns array with statistics:{reads: int, writes: int, failovers: int, readers: int}resetStats(): Resets all statistics counters to zero
Implementations are expected to provide:
- Lazy connection creation
- Load balancing across multiple replicas
- Automatic failover when replicas become unhealthy
- Fallback to writer when no readers are configured
use JardisPort\DbConnection\ConnectionPoolInterface;
use JardisPort\DbConnection\DbConnectionInterface;
// Assuming you have an implementation of ConnectionPoolInterface
// (this package only provides the interface contracts)
/** @var ConnectionPoolInterface $pool */
// Write operations - use the primary database
$writer = $pool->getWriter();
$pdo = $writer->pdo();
$stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (?, ?)');
$stmt->execute(['John Doe', 'john@example.com']);
// Read operations - use a replica database
$reader = $pool->getReader();
$pdo = $reader->pdo();
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([1]);
$user = $stmt->fetch();
// Monitor pool statistics
$stats = $pool->getStats();
echo sprintf(
"Reads: %d, Writes: %d, Failovers: %d, Readers: %d\n",
$stats['reads'],
$stats['writes'],
$stats['failovers'],
$stats['readers']
);
// Reset statistics for new monitoring period
$pool->resetStats();In database replication setups, the primary database handles writes while replicas handle reads. Read/write splitting:
- Scales read operations: Distribute read load across multiple replicas
- Reduces primary load: Offload read queries from the primary database
- Improves performance: Read queries don't compete with write operations
- Provides failover: Automatically handle replica failures
- Enables monitoring: Track read/write patterns and failover events
This approach is particularly beneficial in long-running PHP processes (RoadRunner, Swoole, FrankenPHP) where database connections persist across multiple requests.
# Run PHPStan (level 8)
make phpstan
# Run PHP CodeSniffer (PSR-12)
make phpcsAll commands require Docker Compose and a .env file (see Makefile for details).
MIT License - see LICENSE file for details.
- Jardis Core Development Team