NDT DBF
Single-file PHP Database Framework
Secure by default, compact API, works as a single file or via Composer / PSR-4.
Single file · Composer-ready
Drop-in DBF.php
or install via Composer. Zero extra dependencies.
Secure by default
Prepared statements, identifier quoting, IN-guard, readonly mode, policy hooks.
Enterprise features
Deadlock retry, soft delete, middleware & metrics, keyset pagination.
Easy to use
Clean, beginner-friendly API. Use raw SQL or chainable query builder—your choice.
Free & Open-source
MIT license. Production-ready & built to be forked, extended and audited.
Cross-dialect
MySQL/MariaDB, SQLite, PostgreSQL, SQL Server via PDO. One API across drivers.
Requirements
- PHP 8.1+
- PDO extension for your driver (
pdo_mysql
,pdo_pgsql
,pdo_sqlite
,pdo_sqlsrv
…)
Installation
Composer
bash
composer require ndtan/dbf
PHP
<?php
require __DIR__ . '/vendor/autoload.php';
use ndtan\DBF;
$db = new DBF([
'type' => 'mysql',
'host' => '127.0.0.1',
'database' => 'app',
'username' => 'root',
'password' => 'secret',
'charset' => 'utf8mb4',
]);
Single file
PHP
<?php
require __DIR__ . '/DBF.php';
$db = new ndtan\DBF('mysql://root:secret@127.0.0.1/app?charset=utf8mb4');
Quick start
PHP
<?php
use ndtan\DBF;
// 1) Connect (SQLite demo)
$db = new DBF('sqlite::memory:');
// 2) Schema (SQLite)
$db->raw("CREATE TABLE users (id INTEGER PRIMARY KEY, email TEXT, status TEXT, deleted_at TEXT)");
// 3) Insert
$db->table('users')->insertMany([
['email' => 'p1@ndtan.net', 'status' => 'active'],
['email' => 'p2@ndtan.net', 'status' => 'vip'],
]);
// 4) Select with builder
$rows = $db->table('users')
->select(['id','email'])
->where(['status' => 'active'])
->orderBy('id', 'desc')
->limit(20)
->get();
// 5) Update + Soft delete
$id = $db->table('users')->insert(['email' => 'a@ndtan.net', 'status' => 'vip']);
$db->table('users')->where('id','=', $id)->update(['status' => 'active']);
$db->table('users')->where('id','=', $id)->delete(); // soft delete if enabled
// 6) Transaction with retry
$db->tx(function(DBF $tx){
$oid = $tx->table('orders')->insert(['user_id' => 10, 'total' => 200]);
$tx->table('order_items')->insert(['order_id' => $oid, 'sku' => 'A', 'qty' => 1]);
}, attempts: 3);
// 7) Upsert
$db->table('users')->upsert(
['email' => 'a@ndtan.net', 'status' => 'vip'],
conflict: ['email'],
updateColumns: ['status']
);