PHPackages                             phpdot/database - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. phpdot/database

ActiveLibrary[Database &amp; ORM](/categories/database)

phpdot/database
===============

Query builder, schema management, and migrations for PHP. Built on Doctrine DBAL.

v0.1.1(1mo ago)00MITPHPPHP &gt;=8.5

Since Jul 18Pushed 1mo agoCompare

[ Source](https://github.com/phpdot/database)[ Packagist](https://packagist.org/packages/phpdot/database)[ RSS](/packages/phpdot-database/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (38)Versions (9)Used By (0)

phpdot/database
===============

[](#phpdotdatabase)

A database toolkit for PHP built on [Doctrine DBAL](https://www.doctrine-project.org/projects/dbal.html): a fluent query builder, a schema builder with migrations, typed per-driver connection configs, and production concerns — read/write splitting, sticky routing, automatic reconnection, and slow-query logging — handled behind one `DatabaseConnection`. MySQL, PostgreSQL, and SQLite are supported through driver-specific grammars.

Table of Contents
-----------------

[](#table-of-contents)

- [Requirements](#requirements)
- [Installation](#installation)
- [Usage](#usage)
- [Architecture](#architecture)
- [Testing](#testing)
- [License](#license)

Requirements
------------

[](#requirements)

RequirementConstraintPHP`>= 8.5``doctrine/dbal``^4.4``phpdot/contracts``^0.1``psr/log``^3.0`Bring the PDO driver for your engine (`pdo_mysql`, `pdo_pgsql`, or `pdo_sqlite`). `phpdot/container` is a dev-only suggestion — the `#[Config('database')]` attribute on `DatabaseConfig` is inert until a phpdot application reflects it, so standalone consumers do not need it.

Installation
------------

[](#installation)

```
composer require phpdot/database
```

Usage
-----

[](#usage)

### Connecting

[](#connecting)

Each engine has its own typed config carrying only the keys that engine uses:

```
use PHPdot\Database\DatabaseConnection;
use PHPdot\Database\Connection\MySql\MySqlConfig;
use PHPdot\Database\Connection\Sqlite\SqliteConfig;

$db = new DatabaseConnection(new MySqlConfig(
    database: 'myapp',
    host: '127.0.0.1',
    username: 'root',
));

$memory = new DatabaseConnection(new SqliteConfig(database: ':memory:'));
```

### Query builder

[](#query-builder)

```
$active = $db->table('users')
    ->where('active', true)
    ->whereIn('role', ['admin', 'editor'])
    ->orderBy('created_at', 'desc')
    ->limit(20)
    ->get();

$db->table('users')->insert(['name' => 'Alice', 'email' => 'alice@example.com']);
$db->table('users')->where('id', 1)->update(['active' => false]);
$count = $db->table('orders')->where('status', 'paid')->count();

$page = $db->table('posts')->where('published', true)->paginate(perPage: 15, page: 2);
```

### Schema and migrations

[](#schema-and-migrations)

A migration returns an anonymous class extending `Migration`:

```
use PHPdot\Database\Migration\Migration;
use PHPdot\Database\Schema\Blueprint;
use PHPdot\Database\Schema\SchemaBuilder;

return new class extends Migration {
    public function up(SchemaBuilder $schema): void
    {
        $schema->create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamps();
        });
    }

    public function down(SchemaBuilder $schema): void
    {
        $schema->dropIfExists('users');
    }
};
```

```
use PHPdot\Database\Migration\MigrationRepository;
use PHPdot\Database\Migration\Migrator;

$migrator = new Migrator($db, new MigrationRepository($db));
$migrator->run(__DIR__ . '/migrations');
$migrator->rollback(__DIR__ . '/migrations');
$migrator->pretend(__DIR__ . '/migrations');  // dry run, returns the SQL
```

### Transactions

[](#transactions)

```
$db->transaction(function ($conn) {
    $conn->table('accounts')->where('id', 1)->decrement('balance', 100);
    $conn->table('accounts')->where('id', 2)->increment('balance', 100);
});

// Top-level transactions can retry on deadlock:
$db->transaction(fn ($conn) => /* ... */, maxRetries: 3);
```

### Read/write splitting

[](#readwrite-splitting)

```
use PHPdot\Database\Connection\ConnectionOptions;

$db = new DatabaseConnection(new MySqlConfig(
    database: 'myapp',
    host: 'primary.db.internal',
    options: new ConnectionOptions(
        read: [
            ['host' => 'replica-1.db.internal'],
            ['host' => 'replica-2.db.internal'],
        ],
        sticky: true,
    ),
));
```

SELECTs go to a random replica; writes go to the primary. With `sticky` mode, reads switch to the primary for the rest of the request once a write has happened. Replica entries inherit every key they don't override from the primary block.

Architecture
------------

[](#architecture)

`DatabaseConnection` owns a Doctrine DBAL connection (or a primary plus replicas) and routes each query to the right one. The query and schema builders are engine-agnostic; a per-driver grammar compiles their fluent calls into the SQL dialect for the target engine.

 ```
graph TD
    APP["Application"]
    QB["Query\\Builderfluent select/insert/update/delete"]
    SB["Schema\\SchemaBuilder + Blueprintcreate / alter / drop tables"]
    MIG["Migration\\Migratorrun / rollback / pretend, tracked in a repository"]
    CONN["DatabaseConnectionread/write routing, sticky mode,reconnection, slow-query logging"]
    GRAMMAR["GrammarsMySql / Postgres / Sqlitequery + schema dialects"]
    DBAL["Doctrine DBALprimary + replica PDO connections"]

    APP --> QB
    APP --> SB
    APP --> MIG
    QB --> GRAMMAR
    SB --> GRAMMAR
    MIG --> SB
    GRAMMAR --> CONN
    CONN --> DBAL
```

      Loading Connection configs are typed per driver (`MySqlConfig`, `PostgresConfig`, `SqliteConfig`); `ConnectionFactory` builds the right one from a config block and fails fast, naming the connection and offending key, when a block is misconfigured.

Testing
-------

[](#testing)

```
composer install
composer test        # PHPUnit
composer analyse     # PHPStan, level max + strict rules
composer cs-check    # PHP-CS-Fixer
composer check       # All three
```

The unit suite and the SQLite integration suite (in-memory) run with no external services. The PostgreSQL and MySQL integration suites connect to a real server and **skip automatically when one is not reachable** — point them at a server via the `PG_*` environment variables (PostgreSQL) or a local MySQL on `localhost:3306` to run them.

License
-------

[](#license)

MIT.

**This repository is a read-only mirror**, generated by CI from [phpdot/monorepo](https://github.com/phpdot/monorepo). [Pull requests](https://github.com/phpdot/monorepo/pulls)and [issues](https://github.com/phpdot/monorepo/issues) belong in the monorepo.

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance94

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 81.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~15 days

Total

8

Last Release

31d ago

Major Versions

v1.2.0 → v2.0.02026-05-03

v2.0.1 → v3.0.02026-07-04

PHP version history (3 changes)v1.0.0PHP &gt;=8.3

v2.0.1PHP &gt;=8.4

v0.1.0PHP &gt;=8.5

### Community

Maintainers

![](https://www.gravatar.com/avatar/62e82421bda4b5d6ba9a47ba6d88caca060dcd0d1a2862f351f3a97657385db0?d=identicon)[phpdot](/maintainers/phpdot)

---

Top Contributors

[![phpdot](https://avatars.githubusercontent.com/u/252500?v=4)](https://github.com/phpdot "phpdot (9 commits)")[![o3AM](https://avatars.githubusercontent.com/u/252500?v=4)](https://github.com/o3AM "o3AM (2 commits)")

---

Tags

schemadatabasemysqlsqlitepostgresqldbalmigrationsquery builder

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/phpdot-database/health.svg)

```
[![Health](https://phpackages.com/badges/phpdot-database/health.svg)](https://phpackages.com/packages/phpdot-database)
```

###  Alternatives

[doctrine/dbal

Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.

9.7k614.3M7.4k](/packages/doctrine-dbal)[cycle/database

DBAL, schema introspection, migration and pagination

71811.3k75](/packages/cycle-database)[tommyknocker/pdo-database-class

Framework-agnostic PHP database library with unified API for MySQL, MariaDB, PostgreSQL, SQLite, MSSQL, and Oracle. Query Builder, caching, sharding, window functions, CTEs, JSON, migrations, ActiveRecord, CLI tools, AI-powered analysis. Zero external dependencies.

856.1k](/packages/tommyknocker-pdo-database-class)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
