NDT DBF

Single-file PHP Database Framework

CI php license single-file secure free easy

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']
);