FasterPHP/Db is a high-performance, drop-in replacement for PHP's native PDO class. It enhances standard database operations with advanced features designed for robust, modern applications — all while retaining full compatibility with PDO interfaces and expectations.
If you're tired of dealing with intermittent MySQL timeouts or disconnects, repetitive statement preparation, or clunky connection logic, this package gives you a clean, extensible, and efficient solution that just works — no learning curve required.
Key features:
- ✅ Drop-in
PDOreplacement (extendsPDO, not just wraps it) - 🔁 Auto-reconnect on lost or timed-out connections with configurable retry/backoff
- 🛡️ Transaction-aware reconnect protection
- 🔄 Lazy-loading and internal connection pooling
- ⚡️ Prepared statement caching for reduced overhead
- 📝 Optional PSR-3 logging support
- 🧱 Custom
DbStatementclass for enhanced control
composer require fasterphp/db- PHP 8.2 or higher
- A supported PDO database (e.g. MySQL, PostgreSQL, SQLite, etc.)
- PDO extension (
ext-pdo)
use FasterPhp\Db\Db;
$db = new Db(
dsn: 'mysql:host=localhost;dbname=mydb',
username: 'myuser',
password: 'mysecret',
);
$stmt = $db->prepare('SELECT * FROM users WHERE id = :id');
$stmt->execute([':id' => 1]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);If a connection is lost (e.g. due to a timeout), FasterPhp\Db automatically reconnects, re-prepares (where necessary), and re-executes the statement.
The DefaultStrategy supports configurable retry attempts with exponential backoff:
use FasterPhp\Db\Db;
use FasterPhp\Db\Reconnect\DefaultStrategy;
$strategy = new DefaultStrategy(
maxAttempts: 3, // Try up to 3 times (default: 1)
baseDelayMs: 100, // Start with 100ms delay (default: 100)
backoffMultiplier: 2.0 // Double the delay each attempt (default: 2.0)
);
$db = new Db(
dsn: 'mysql:host=localhost;dbname=mydb',
username: 'myuser',
password: 'mysecret',
reconnectStrategy: $strategy
);With these settings, reconnect attempts will wait 100ms, then 200ms, then 400ms between retries.
Reconnecting mid-transaction would silently lose uncommitted changes. FasterPhp\Db prevents this by throwing a DbException if a reconnectable error occurs during an active transaction:
$db->beginTransaction();
$db->exec('INSERT INTO users (name) VALUES ("Alice")');
// If connection is lost here, DbException is thrown instead of reconnecting
// This prevents silent data lossThis protection works for both explicit transactions (beginTransaction()) and raw SQL transactions (BEGIN/START TRANSACTION).
You can attach a PSR-3 compatible logger to monitor reconnect events:
use Psr\Log\LoggerInterface;
$db->setLogger($logger);
// Reconnect events are logged at WARNING level with DSN and error detailsYou can configure reconnect patterns via Config\ArrayProvider or inject a custom ReconnectStrategy by implementing Reconnect\StrategyInterface.
Prepared statements are cached internally to avoid repeated preparation overhead:
$stmt1 = $db->prepare('SELECT * FROM users WHERE id = :id');
$stmt2 = $db->prepare('SELECT * FROM users WHERE id = :id');
// $stmt1 === $stmt2To clear the statement cache (e.g. after schema changes or to free memory):
$db->clearStatementCache();The ConnectionManager class enables application-wide connection pooling and shared configuration. It’s ideal for large applications, services, or frameworks that require multiple named database instances or shared lifecycle control.
use FasterPhp\Db\ConnectionManager;
use FasterPhp\Db\Config\ArrayProvider;
$config = new ArrayProvider([
'main' => [
'dsn' => 'mysql:host=127.0.0.1;dbname=main_db',
'username' => 'root',
'password' => '',
'options' => [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
],
],
'analytics' => [
'dsn' => 'mysql:host=127.0.0.1;dbname=analytics',
'username' => 'readonly',
'password' => '',
],
]);
$manager = new ConnectionManager($config);
// Get a shared Db instance
$db = $manager->get('main');💡
ConnectionManagerwill automatically reuse idle connections if available.
The Config\ArrayProvider class is a simple implementation of the ProviderInterface that lets you define connection settings in plain PHP arrays.
To use a different configuration source (like .env, JSON, or YAML), implement:
interface ProviderInterface {
public function get(string $name): ?array;
}This keeps your configuration logic separate from your application logic, and makes it easy to test or extend.
Tests require a MySQL server with a testdb database. You can configure your environment using .env variables or phpunit.xml:
DB_DSN="mysql:host=127.0.0.1;dbname=testdb"
DB_USER="root"
DB_PASS=""
Run tests with:
vendor/bin/phpunitTo generate a coverage report (requires Xdebug or PCOV):
vendor/bin/phpunit --coverage-html build/coverageContributions are welcome! To get started:
- Fork the repository
- Create a new branch (
git checkout -b feature/my-feature) - Commit your changes (
git commit -am 'Add feature') - Push to the branch (
git push origin feature/my-feature) - Open a pull request
Please be respectful and constructive in all interactions. We aim to foster a professional, welcoming environment.
If you discover a security vulnerability, please report it privately via GitHub or email the maintainer. Avoid opening public issues for sensitive disclosures.
This package is open-source software licensed under the MIT license.