- Notifications
You must be signed in to change notification settings - Fork48
Lightweight PHP database library with unified API for MySQL, MariaDB, PostgreSQL, SQLite & MSSQL. QueryBuilder, caching, sharding, window functions, CTEs, JSON, migrations, ActiveRecord. Zero dependencies.
License
tommyknocker/pdo-database-class
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
PDOdb is a lightweight, framework-agnostic PHP database library providing aunified API across MySQL, MariaDB, PostgreSQL, SQLite, Microsoft SQL Server (MSSQL), and Oracle.
Built on top of PDO withzero external dependencies, it offers:
Core Features:
- Fluent Query Builder - Intuitive, chainable API for all database operations
- Cross-Database Compatibility - Automatic SQL dialect handling (MySQL, MariaDB, PostgreSQL, SQLite, MSSQL, Oracle)
- 80+ Helper Functions - SQL helpers for strings, dates, math, JSON, aggregations, and more (REPEAT, REVERSE, LPAD, RPAD emulated for SQLite; REGEXP operations supported across all dialects)
Performance:
- Query Caching - PSR-16 integration for result caching (10-1000x faster repeated queries)
- Query Compilation Cache - Cache compiled SQL strings (10-30% performance improvement)
- Prepared Statement Pool - Automatic statement caching with LRU eviction (20-50% faster repeated queries)
- Query Performance Profiling - Built-in profiler for tracking execution times, memory usage, and slow query detection
Advanced Features:
- Window Functions - Advanced analytics with ROW_NUMBER, RANK, LAG, LEAD, running totals, moving averages
- Common Table Expressions (CTEs) - WITH clauses for complex queries, recursive CTEs for hierarchical data, materialized CTEs for performance optimization
- LATERAL JOINs - Correlated subqueries in FROM clause for PostgreSQL, MySQL, and MSSQL (CROSS APPLY/OUTER APPLY)
- Set Operations - UNION, INTERSECT, EXCEPT for combining query results with automatic deduplication
- JSON Operations - Native JSON support with consistent API across all databases
- Full-Text Search - Cross-database FTS with unified API (MySQL FULLTEXT, PostgreSQL tsvector, SQLite FTS5)
- Read/Write Splitting - Horizontal scaling with master-replica architecture and load balancing
- Sharding - Horizontal partitioning across multiple databases with automatic query routing (range, hash, modulo strategies)
- ActiveRecord Pattern - Optional lightweight ORM for object-based database operations with relationships (hasOne, hasMany, belongsTo, hasManyThrough), eager/lazy loading, and query scopes
Developer Experience:
- CLI Tools - Database management, user management, dump/restore, migration generator, seed generator, model generator, schema inspector, and interactive query tester (REPL)
- Enhanced EXPLAIN - Automatic detection of full table scans, missing indexes, and optimization recommendations
- Exception Hierarchy - Typed exceptions for precise error handling
- Enhanced Error Diagnostics - Query context, sanitized parameters, and debug information in exceptions
- SQL Formatter/Pretty Printer - Human-readable SQL output for debugging with indentation and line breaks
- Query Debugging - Comprehensive debug information and query inspection tools
- PSR-14 Event Dispatcher - Event-driven architecture for monitoring, auditing, and middleware
- Plugin System - Extend PdoDb with custom plugins for macros, scopes, and event listeners
Production Ready:
- Fully Tested - 2325 tests, 7759 assertions across all dialects
- Type-Safe - PHPStan level 8 validated, PSR-12 compliant
- Zero Memory Leaks - Production-tested memory management with automatic cursor cleanup
- Connection Retry - Automatic retry with exponential backoff
- Transactions & Locking - Full transaction support with table locking and savepoints for nested transactions
- Batch Processing - Memory-efficient generators for large datasets with zero memory leaks
Additional Capabilities:
- Bulk Operations - CSV/XML/JSON loaders, multi-row inserts, UPSERT support
- INSERT ... SELECT - Fluent API for copying data between tables with QueryBuilder, subqueries, and CTE support
- UPDATE/DELETE with JOIN - Update and delete operations with JOIN clauses (MySQL/MariaDB/PostgreSQL/MSSQL)
- MERGE Statements - INSERT/UPDATE/DELETE based on match conditions (PostgreSQL/MSSQL native, MySQL/SQLite emulated)
- Schema Introspection - Query indexes, foreign keys, and constraints programmatically
- DDL Query Builder - Production-ready fluent API for creating, altering, and managing database schema (tables, columns, indexes, foreign keys, constraints) with Yii2-style methods, partial indexes, fulltext/spatial indexes, cross-dialectal support, anddialect-specific types (MySQL ENUM/SET, PostgreSQL UUID/JSONB/arrays, MSSQL UNIQUEIDENTIFIER/NVARCHAR, SQLite type affinity)
- Database Migrations - Version-controlled schema changes with rollback support (Yii2-inspired)
- Database Seeds - Populate database with initial or test data, batch tracking, rollback support
- Advanced Pagination - Full, simple, and cursor-based pagination with metadata
- Export Helpers - Export results to JSON, CSV, and XML formats
- DISTINCT & DISTINCT ON - Remove duplicates with full PostgreSQL DISTINCT ON support
- FILTER Clause - Conditional aggregates (SQL:2003 standard) with automatic MySQL fallback to CASE WHEN
Inspired byThingEngineer/PHP-MySQLi-Database-Class andYii2 framework
Perfect for:
- ✅Beginners - Simple, intuitive API with zero configuration needed
- ✅Cross-database projects - Switch between MySQL, PostgreSQL, SQLite, MSSQL, Oracle without code changes
- ✅Performance-critical apps - Built-in caching, query optimization, profiling
- ✅Modern PHP - Type-safe, PSR-compliant, PHP 8.4+ features
vs. Raw PDO:
- ✅ Fluent query builder instead of manual SQL strings
- ✅ Automatic parameter binding (SQL injection protection built-in)
- ✅ Cross-database compatibility out of the box
- ✅ Helper functions for common operations
vs. Eloquent/Doctrine:
- ✅ Zero dependencies (no framework required)
- ✅ Lightweight (no ORM overhead)
- ✅ Direct SQL access when needed
- ✅ Better performance for complex queries
- ✅ Optional ActiveRecord pattern available
- Requirements
- Installation
- 📖 Documentation
- 📚 Examples
- Quick Example
- 5-Minute Tutorial
- Configuration
- Quick Start
- JSON Operations
- Advanced Usage
- CLI Tools
- Error Handling
- Performance Tips
- Helper Functions
- API Reference
- Dialect Differences
- Frequently Asked Questions
- Migration Guide
- Troubleshooting
- Testing
- Contributing
- License
- PHP: 8.4 or higher
- PDO Extensions:
pdo_mysqlfor MySQL/MariaDBpdo_pgsqlfor PostgreSQLpdo_sqlitefor SQLitesqlsrvfor Microsoft SQL Server (requires Microsoft ODBC Driver for SQL Server)ocifor Oracle Database
- Supported Databases:
- MySQL 5.7+ / MariaDB 10.3+
- PostgreSQL 9.4+
- SQLite 3.38+
- Microsoft SQL Server 2019+ / Azure SQL Database
- Oracle Database 12c+
Check if your SQLite has JSON support:
sqlite3 :memory:"SELECT json_valid('{}')"Install via Composer:
composer require tommyknocker/pdo-database-class
For specific versions:
# Latest 2.x versioncomposer require tommyknocker/pdo-database-class:^2.0# Latest 1.x versioncomposer require tommyknocker/pdo-database-class:^1.0# Development versioncomposer require tommyknocker/pdo-database-class:dev-master
Fastest way to get started: Use the interactive wizard to configure your project:
vendor/bin/pdodb init
The wizard will guide you through:
- Database connection settings (MySQL, PostgreSQL, SQLite, MSSQL, Oracle)
- Configuration file format (
.envorconfig/db.php) - Directory structure creation (migrations, models, repositories, services)
- Connection testing
- Advanced options (caching, table prefix, multiple connections)
SeeCLI Tools Documentation for more details.
Complete documentation is available in thedocumentation/ directory with 56+ detailed guides covering all features:
- Getting Started - Installation, configuration, your first connection
- Core Concepts - Connection management, query builder, parameter binding, dialects
- Query Builder - SELECT, DML, filtering, joins, aggregations, subqueries
- JSON Operations - Working with JSON across all databases
- Advanced Features - Transactions, batch processing, bulk operations, UPSERT, query scopes, query macros, plugin system
- Error Handling - Exception hierarchy, enhanced error diagnostics with query context, retry logic, logging, monitoring
- Helper Functions - Complete reference for all helper functions
- Best Practices - Security, performance, memory management, code organization
- API Reference - Complete API documentation
- Cookbook - Common patterns, real-world examples, troubleshooting
Each guide includes working code examples, dialect-specific notes, security considerations, and best practices.
Start here:Documentation Index
Comprehensive, runnable examples are available in theexamples/ directory:
- Basic - Connection, CRUD, WHERE conditions
- Intermediate - JOINs, aggregations, pagination, transactions, savepoints
- Advanced - Connection pooling, bulk operations, UPSERT, subqueries, MERGE, window functions, CTEs
- JSON Operations - Complete guide to JSON features
- Helper Functions - String, math, date/time, NULL, comparison helpers
- Performance - Query caching, compilation cache, profiling, EXPLAIN analysis
- ActiveRecord - Object-based operations, relationships, scopes
Each example is self-contained with setup instructions. Seeexamples/README.md for the full catalog.
Quick start:
cd examples# SQLite (ready to use, no setup required)php 01-basic/02-simple-crud.php# MySQL (update config.mysql.php with your credentials)PDODB_DRIVER=mysql php 01-basic/02-simple-crud.php# Test all examples on all available databases./scripts/test-examples.sh
Fastest start: Runvendor/bin/pdodb init for interactive setup, or get started manually:
usetommyknocker\pdodb\PdoDb;// Connect (SQLite - no setup needed!)$db =newPdoDb('sqlite', ['path' =>':memory:']);// Create table$db->rawQuery('CREATE TABLE users ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, email TEXT, age INTEGER)');// Insert$id =$db->find()->table('users')->insert(['name' =>'John','email' =>'john@example.com','age' =>30]);// Query$users =$db->find() ->from('users') ->where('age',18,'>') ->orderBy('name','ASC') ->limit(10) ->get();// Update$db->find() ->table('users') ->where('id',$id) ->update(['age' =>31]);
That's it! No configuration, no dependencies, just works.
composer require tommyknocker/pdo-database-class
Use the interactive wizard:
vendor/bin/pdodb init
Alternative: Manual configuration
usetommyknocker\pdodb\PdoDb;// SQLite (easiest - no database server needed)$db =newPdoDb('sqlite', ['path' =>':memory:']);// Or MySQL/PostgreSQL$db =newPdoDb('mysql', ['host' =>'localhost','dbname' =>'mydb','username' =>'user','password' =>'pass']);
// Simple approach (raw SQL)$db->rawQuery('CREATE TABLE users ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, email TEXT, age INTEGER)');// Or use DDL Query Builder$db->schema()->createTable('products', ['id' =>$db->schema()->primaryKey(),'name' =>$db->schema()->string(255)->notNull(),'status' =>$db->schema()->enum(['draft','published','archived']) ->defaultValue('draft'),'created_at' =>$db->schema()->timestamp()->defaultExpression('CURRENT_TIMESTAMP')]);
// Create$id =$db->find()->table('users')->insert(['name' =>'Alice','email' =>'alice@example.com','age' =>30]);// Read$users =$db->find()->from('users')->get();$user =$db->find()->from('users')->where('id',$id)->getOne();// Update$db->find()->table('users') ->where('id',$id) ->update(['name' =>'Bob']);// Delete$db->find()->table('users')->where('id',$id)->delete();
Next: SeeQuick Start for more examples.
usetommyknocker\pdodb\PdoDb;// MySQL$db =newPdoDb('mysql', ['host' =>'127.0.0.1','username' =>'testuser','password' =>'testpass','dbname' =>'testdb','port' =>3306,'charset' =>'utf8mb4',]);// PostgreSQL$db =newPdoDb('pgsql', ['host' =>'127.0.0.1','username' =>'testuser','password' =>'testpass','dbname' =>'testdb','port' =>5432,]);// SQLite$db =newPdoDb('sqlite', ['path' =>'/path/to/database.sqlite',// or ':memory:' for in-memory]);// MSSQL$db =newPdoDb('sqlsrv', ['host' =>'localhost','username' =>'testuser','password' =>'testpass','dbname' =>'testdb','port' =>1433,]);
Connection Pooling:
$db =newPdoDb();$db->addConnection('mysql_main', ['driver' =>'mysql', ...]);$db->addConnection('pgsql_analytics', ['driver' =>'pgsql', ...]);$db->connection('mysql_main')->find()->from('users')->get();
Read/Write Splitting:
$db->enableReadWriteSplitting(newRoundRobinLoadBalancer());$db->addConnection('master', [...], ['type' =>'write']);$db->addConnection('replica-1', [...], ['type' =>'read']);// SELECTs automatically go to replicas, DML to master
Query Caching:
$cache = CacheFactory::create(['type' =>'filesystem','directory' =>'/var/cache']);$db =newPdoDb('mysql',$config, [],null,$cache);$users =$db->find()->from('users')->cache(3600)->get();
SeeConfiguration Documentation for complete configuration options.
Note: All query examples start with$db->find() which returns aQueryBuilder instance.
// SELECT$user =$db->find() ->from('users') ->where('id',10) ->getOne();$users =$db->find() ->from('users') ->where('age',18,'>=') ->get();// INSERT$id =$db->find()->table('users')->insert(['name' =>'Alice','email' =>'alice@example.com','age' =>30]);// UPDATE$db->find() ->table('users') ->where('id',$id) ->update(['age' =>31]);// DELETE$db->find() ->table('users') ->where('id',$id) ->delete();
usetommyknocker\pdodb\helpers\Db;// WHERE conditions$users =$db->find() ->from('users') ->where('status','active') ->andWhere('age',18,'>') ->andWhere(Db::like('email','%@example.com')) ->get();// JOIN and GROUP BY$stats =$db->find() ->from('users AS u') ->select(['u.id','u.name','total' => Db::sum('o.amount')]) ->leftJoin('orders AS o','o.user_id = u.id') ->groupBy('u.id') ->having(Db::sum('o.amount'),1000,'>') ->get();
$db->startTransaction();try {$userId =$db->find()->table('users')->insert(['name' =>'Alice']);$db->find()->table('orders')->insert(['user_id' =>$userId,'total' =>100]);$db->commit();}catch (\Exception$e) {$db->rollback();}
SeeQuery Builder Documentation for more examples.
PDOdb provides a unified JSON API that works consistently across all databases.
usetommyknocker\pdodb\helpers\Db;// Create JSON data$db->find()->table('users')->insert(['name' =>'John','meta' => Db::jsonObject(['city' =>'NYC','age' =>30]),'tags' => Db::jsonArray('php','mysql','docker')]);// Query JSON$adults =$db->find() ->from('users') ->where(Db::jsonPath('meta', ['age'],'>',25)) ->get();// Extract JSON values$users =$db->find() ->from('users') ->select(['id','name','city' => Db::jsonGet('meta', ['city']) ]) ->get();// Update JSON$db->find() ->table('users') ->where('id',1) ->update(['meta' => Db::jsonSet('meta', ['city'],'London') ]);
SeeJSON Operations Documentation for complete guide.
$users =$db->rawQuery('SELECT * FROM users WHERE age > :age', ['age' =>18]);
$users =$db->find() ->from('users') ->whereIn('id',function($query) {$query->from('orders') ->select('user_id') ->where('total',1000,'>'); }) ->get();
// Full pagination (with total count)$result =$db->find() ->from('posts') ->orderBy('created_at','DESC') ->paginate(20,1);// Cursor pagination (most efficient)$result =$db->find() ->from('posts') ->orderBy('id','DESC') ->cursorPaginate(20);
// Process in batchesforeach ($db->find()->from('users')->batch(100)as$batch) {foreach ($batchas$user) {processUser($user); }}// Stream results (minimal memory)foreach ($db->find()->from('users')->stream()as$user) {processUser($user);}
// Cache for 1 hour$products =$db->find() ->from('products') ->where('category','Electronics') ->cache(3600) ->get();
SeeAdvanced Features Documentation for complete guide.
PDOdb provides convenient command-line tools for common development tasks:
vendor/bin/pdodb<command> [subcommand] [arguments] [options]
db- Manage databases (create, drop, list, check existence)user- Manage database users (create, drop, grant/revoke privileges)dump- Dump and restore database (with compression, auto-naming, rotation)migrate- Manage database migrationsschema- Inspect database schemaquery- Test SQL queries interactively (REPL)model- Generate ActiveRecord modelstable- Manage tables (info, create, drop, truncate)monitor- Monitor database queries and performance
Install bash completion for enhanced CLI experience:
# Temporary (current session)source<(curl -s https://raw.githubusercontent.com/tommyknocker/pdo-database-class/refs/heads/master/scripts/pdodb-completion.bash)# Permanentcurl -o~/.pdodb-completion.bash https://raw.githubusercontent.com/tommyknocker/pdo-database-class/refs/heads/master/scripts/pdodb-completion.bashecho"source ~/.pdodb-completion.bash">>~/.bashrc
# Create databasevendor/bin/pdodb db create myapp# Dump with compression and rotationvendor/bin/pdodb dump --auto-name --compress=gzip --rotate=7# Create migrationvendor/bin/pdodb migrate create create_users_table# Generate modelvendor/bin/pdodb model make User users app/Models
SeeCLI Tools Documentation for complete guide.
PDOdb provides a comprehensive exception hierarchy for better error handling:
usetommyknocker\pdodb\exceptions\{DatabaseException,ConnectionException,QueryException,ConstraintViolationException,TransactionException};try {$users =$db->find()->from('users')->get();}catch (ConnectionException$e) {// Handle connection errorsif ($e->isRetryable()) {// Implement retry logic }}catch (QueryException$e) {// Handle query errorserror_log("Query:" .$e->getQuery());error_log("Context:" .$e->getDescription());}catch (ConstraintViolationException$e) {// Handle constraint violationserror_log("Constraint:" .$e->getConstraintName());}
All exceptions extendPDOException for backward compatibility and provide rich context information.
SeeError Handling Documentation for complete guide.
For applications with repeated queries, enable result caching:
$cache =newPsr16Cache(newFilesystemAdapter());$db =newPdoDb('mysql',$config, [],null,$cache);$products =$db->find() ->from('products') ->where('category','Electronics') ->cache(3600) ->get();
Performance Impact: 65-97% faster for repeated queries with cache hits.
// ❌ Slow: Multiple single insertsforeach ($usersas$user) {$db->find()->table('users')->insert($user);}// ✅ Fast: Single batch insert$db->find()->table('users')->insertMulti($users);
// ✅ Safe: Limited results$users =$db->find()->from('users')->limit(1000)->get();
// Process in chunksforeach ($db->find()->from('users')->batch(100)as$batch) {processBatch($batch);}
SeePerformance Documentation for more tips.
PDOdb provides 80+ helper functions for common SQL operations:
Core Helpers:
Db::raw()- Raw SQL expressionsDb::concat()- String concatenationDb::now()- Current timestamp
String Operations:
Db::upper(),Db::lower(),Db::trim(),Db::substring(),Db::replace()
Numeric Operations:
Db::inc(),Db::dec(),Db::abs(),Db::round(),Db::mod()
Date/Time Functions:
Db::now(),Db::date(),Db::year(),Db::month(),Db::day()
JSON Operations:
Db::jsonObject(),Db::jsonArray(),Db::jsonGet(),Db::jsonPath(),Db::jsonContains()
Aggregate Functions:
Db::count(),Db::sum(),Db::avg(),Db::min(),Db::max()
Full Reference: SeeHelper Functions Documentation for complete list and examples.
| Method | Description |
|---|---|
find() | Returns QueryBuilder instance |
rawQuery(string, array) | Execute raw SQL, returns array of rows |
rawQueryOne(string, array) | Execute raw SQL, returns first row |
startTransaction() | Begin transaction |
commit() | Commit transaction |
rollBack() | Roll back transaction |
describe(string) | Get table structure |
indexes(string) | Get all indexes for a table |
keys(string) | Get foreign key constraints |
Table & Selection:
table(string)/from(string)- Set target tableselect(array|string)- Specify columns to select
Filtering:
where(...)/andWhere(...)/orWhere(...)- Add WHERE conditionswhereIn(...)/whereNotIn(...)- IN / NOT IN conditionswhereNull(...)/whereNotNull(...)- NULL checkswhereBetween(...)- BETWEEN conditionsjoin(...)/leftJoin(...)/rightJoin(...)- Add JOIN clauses
Data Manipulation:
insert(array)- Insert single rowinsertMulti(array)- Insert multiple rowsupdate(array)- Update rowsdelete()- Delete rows
Execution:
get()- Execute SELECT, return all rowsgetOne()- Execute SELECT, return first rowgetValue()- Execute SELECT, return single value
Full Reference: SeeAPI Reference Documentation for complete method list and signatures.
PDOdb handles most differences automatically, but here are some key points:
UPSERT:
- MySQL:
ON DUPLICATE KEY UPDATE - PostgreSQL/SQLite:
ON CONFLICT ... DO UPDATE SET
UseonDuplicate() for portable UPSERT:
$db->find()->table('users')->onDuplicate(['age' => Db::inc()])->insert(['email' =>'user@example.com','age' =>25]);
JSON Functions:
- MySQL: Uses
JSON_EXTRACT,JSON_CONTAINS - PostgreSQL: Uses
->,->>,@>operators - SQLite: Uses
json_extract,json_each
All handled transparently throughDb::json*() helpers.
Full Reference: SeeDialect Differences Documentation for complete guide.
No, PDOdb is aquery builder with optional ActiveRecord pattern. It's lighter than full ORMs like Eloquent or Doctrine.
Yes! UserawQuery() for complete control:
$users =$db->rawQuery('SELECT * FROM users WHERE age > :age', ['age' =>18]);
Yes! PDOdb is framework-agnostic. Works with Laravel, Symfony, Yii, or no framework at all.
Yes! 2325+ tests, PHPStan level 8, used in production environments.
All queries useprepared statements automatically. SQL injection protection is built-in.
Yes! Pass your PDO instance:
$pdo =newPDO('mysql:host=localhost;dbname=test','user','pass');$db =newPdoDb('mysql', ['pdo' =>$pdo]);
SQLite is perfect for development - no server setup needed:
$db =newPdoDb('sqlite', ['path' =>':memory:']);
Yes! Full transaction support with savepoints:
$db->startTransaction();try {// Your operations$db->commit();}catch (\Exception$e) {$db->rollBack();}
Before:
$pdo =newPDO('mysql:host=localhost;dbname=test','user','pass');$stmt =$pdo->prepare('SELECT * FROM users WHERE age > :age');$stmt->execute(['age' =>18]);$users =$stmt->fetchAll(PDO::FETCH_ASSOC);
After:
$db =newPdoDb('mysql', ['host' =>'localhost','dbname' =>'test','username' =>'user','password' =>'pass']);$users =$db->find()->from('users')->where('age',18,'>')->get();
Before:
User::where('active',1) ->where('age','>',18) ->orderBy('name') ->limit(10) ->get();
After:
$db->find() ->from('users') ->where('active',1) ->andWhere('age',18,'>') ->orderBy('name','ASC') ->limit(10) ->get();
SeeMigration Guide Documentation for more examples.
Solution: Install the required PHP extension:
sudo apt-get install php8.4-mysql php8.4-pgsql php8.4-sqlite3
Solution: Check if JSON support is available:
sqlite3 :memory:"SELECT json_valid('{}')"Problem: Using OFFSET without LIMIT in SQLite.
Solution: Always use LIMIT with OFFSET:
// ✅ Works$db->find()->from('users')->limit(20)->offset(10)->get();
Solution: Use batch processing or streaming:
foreach ($db->find()->from('users')->batch(100)as$batch) {processBatch($batch);}
SeeTroubleshooting Documentation for more solutions.
The project includes comprehensive PHPUnit tests for all supported databases.
# Run all tests./vendor/bin/phpunit# Run specific dialect tests./vendor/bin/phpunit tests/PdoDbMySQLTest.php# Run with coverage./vendor/bin/phpunit --coverage-html coverage
- MySQL/MariaDB: Running instance on localhost:3306
- PostgreSQL: Running instance on localhost:5432
- SQLite: No setup required (uses
:memory:) - MSSQL: Running instance on localhost:1433
- Oracle: Running instance on localhost:1521 (requires Oracle Instant Client and
pdo_ociextension)
Contributions are welcome! Please follow these guidelines:
- Open an issue first for new features or bug reports
- Include failing tests that demonstrate the problem
- Follow PSR-12 coding standards
- Write tests for all new functionality
- Test against all six dialects (MySQL, MariaDB, PostgreSQL, SQLite, MSSQL, Oracle)
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is open source. SeeLICENSE file for details.
Inspired byThingEngineer/PHP-MySQLi-Database-Class andYii2 framework
Built with ❤️ for the PHP community.
About
Lightweight PHP database library with unified API for MySQL, MariaDB, PostgreSQL, SQLite & MSSQL. QueryBuilder, caching, sharding, window functions, CTEs, JSON, migrations, ActiveRecord. Zero dependencies.
Topics
Resources
License
Code of conduct
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.