<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>NDT DBF — A single-file PHP Database Framework (PRO · Enterprise+). Secure by default, compact API.</title>

<link rel="icon" href="/assets/favicon.ico">
<link rel="canonical" href="https://ndtan.net/share/rss.xml">

<!-- Basic SEO -->
<meta name="description" content="A single-file PHP Database Framework (PRO · Enterprise+). Secure by default, compact API.">
<meta name="robots" content="index,follow,max-snippet:-1,max-image-preview:large,max-video-preview:-1">
<meta name="author" content="Tony Nguyen">
<meta name="generator" content="NDT DBF Docs">
<meta name="application-name" content="NDT DBF">
<meta name="theme-color" content="#0b1324">
<meta name="color-scheme" content="dark light">
<meta name="format-detection" content="telephone=no">

<!-- Open Graph -->
<meta property="og:type" content="website">
<meta property="og:site_name" content="NDT DBF">
<meta property="og:title" content="NDT DBF — A single-file PHP Database Framework (PRO · Enterprise+). Secure by default, compact API.">
<meta property="og:description" content="A single-file PHP Database Framework (PRO · Enterprise+). Secure by default, compact API.">
<meta property="og:url" content="https://ndtan.net/share/rss.xml">
<meta property="og:image" content="/assets/img/og.png">
<meta property="og:locale" content="en_US">

<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="NDT DBF — A single-file PHP Database Framework (PRO · Enterprise+). Secure by default, compact API.">
<meta name="twitter:description" content="A single-file PHP Database Framework (PRO · Enterprise+). Secure by default, compact API.">
<meta name="twitter:image" content="/assets/img/og.png">

<!-- Preconnect (CDNs/GitHub) -->
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
<link rel="preconnect" href="https://github.com" crossorigin>
<link rel="preconnect" href="https://avatars.githubusercontent.com" crossorigin>

<!-- Base styles -->

<link rel="stylesheet" href="/assets/css/docs.css">

<!-- Prism (theme + plugins) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1/themes/prism-tomorrow.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1/plugins/line-numbers/prism-line-numbers.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1/plugins/toolbar/prism-toolbar.min.css">

<!-- JSON-LD: SoftwareSourceCode -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "SoftwareSourceCode",
  "name": "NDT DBF",
  "description": "A single-file PHP Database Framework (PRO \u00b7 Enterprise+). Secure by default, compact API.",
  "url": "https:\/\/ndtan.net",
  "codeRepository": "https:\/\/github.com\/nguyenduytan\/NDT-DBF",
  "programmingLanguage": "PHP",
  "applicationCategory": "DeveloperLibrary",
  "operatingSystem": "Cross-platform",
  "creator": {
    "@type": "Person",
    "name": "Tony Nguyen",
    "url": "https:\/\/nguyenduytan.com",
    "email": "admin@ndtan.net"  },
  "license": "https://opensource.org/licenses/MIT",
  "offers": {
    "@type": "Offer",
    "price": "0",
    "priceCurrency": "USD"
  },
  "downloadUrl": "https:\/\/raw.githubusercontent.com\/nguyenduytan\/NDT-DBF\/main\/src\/DBF.php",
  "image": "\/assets\/img\/og.png",
  "sameAs": ["https:\/\/github.com\/nguyenduytan\/NDT-DBF", "https:\/\/nguyenduytan.com"]
}
</script>

<!-- JSON-LD: WebSite (optional, helps site-level SEO) -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "WebSite",
  "name": "NDT DBF",
  "url": "https:\/\/ndtan.net",
  "potentialAction": {
    "@type": "SearchAction",
    "target": "https:\/\/ndtan.net\/docs#intro?q={search_term_string}",
    "query-input": "required name=search_term_string"
  }
}
</script>

</head>
<body>

<header class="site-header">
  <div class="wrap">
    <a class="brand" href="/">
      <span class="brand-mark">NDT</span><span class="brand-suffix">DBF</span>
    </a>
    <nav class="nav">
      <a class="btn btn-ghost" href="https://raw.githubusercontent.com/nguyenduytan/NDT-DBF/main/src/DBF.php" download>Download</a>
      <a class="btn btn-ghost" href="/docs">Docs</a>
      <a class="btn btn-ghost" href="https://github.com/nguyenduytan/NDT-DBF" target="_blank" rel="noopener">Fork</a>
    </nav>
  </div>
</header>

<main>

  <!-- HERO -->
  <section class="hero">
    <div class="wrap hero-inner">
      <h1 class="hero-title glow-anim">NDT DBF</h1>
      <p class="hero-sub">Single-file PHP Database Framework</p>

      <div class="badges">
        <img alt="CI"          src="https://img.shields.io/github/actions/workflow/status/nguyenduytan/NDT-DBF/ci.yml?label=ci&logo=github">
        <img alt="php"         src="https://img.shields.io/badge/php-%3E%3D%208.1-777bb4">
        <img alt="license"     src="https://img.shields.io/badge/license-MIT-brightgreen">
        <img alt="single-file" src="https://img.shields.io/badge/single--file-yes-informational">
        <img alt="secure"      src="https://img.shields.io/badge/secure%20by-default-success">
        <img alt="free"        src="https://img.shields.io/badge/free%20%26%20open--source-100%25-blue">
        <img alt="easy"        src="https://img.shields.io/badge/easy-API-orange">
      </div>

      <div class="hero-cta">
        <a class="btn btn-primary" href="https://raw.githubusercontent.com/nguyenduytan/NDT-DBF/main/src/DBF.php" download>Download DBF.php</a>
        <a class="btn btn-dark"    href="https://github.com/nguyenduytan/NDT-DBF" target="_blank" rel="noopener">Fork on GitHub</a>
        <a class="btn btn-outline" href="/docs">Documentation</a>
        <a class="btn btn-accent"  href="https://www.paypal.com/paypalme/copbeo" target="_blank" rel="noopener">Donate</a>
      </div>

      <p class="hero-note">Secure by default, compact API, works as a <strong>single file</strong> or via <strong>Composer / PSR-4</strong>.</p>
    </div>
  </section>

  <!-- FEATURES -->
  <section class="features">
    <div class="wrap grid">
      <div class="card">
        <h3>Single file · Composer-ready</h3>
        <p>Drop-in <code>DBF.php</code> or install via Composer. Zero extra dependencies.</p>
      </div>
      <div class="card">
        <h3>Secure by default</h3>
        <p>Prepared statements, identifier quoting, IN-guard, readonly mode, policy hooks.</p>
      </div>
      <div class="card">
        <h3>Enterprise features</h3>
        <p>Deadlock retry, soft delete, middleware &amp; metrics, keyset pagination.</p>
      </div>

      <div class="card">
        <h3>Easy to use</h3>
        <p>Clean, beginner-friendly API. Use raw SQL or chainable query builder—your choice.</p>
      </div>
      <div class="card">
        <h3>Free &amp; Open-source</h3>
        <p>MIT license. Production-ready &amp; built to be forked, extended and audited.</p>
      </div>
      <div class="card">
        <h3>Cross-dialect</h3>
        <p>MySQL/MariaDB, SQLite, PostgreSQL, SQL Server via PDO. One API across drivers.</p>
      </div>
    </div>
  </section>

  <!-- REQUIREMENTS -->
  <section class="section">
    <div class="wrap">
      <div class="panel">
        <h2>Requirements</h2>
        <ul class="check">
          <li>PHP <strong>8.1+</strong></li>
          <li>PDO extension for your driver (<code>pdo_mysql</code>, <code>pdo_pgsql</code>, <code>pdo_sqlite</code>, <code>pdo_sqlsrv</code> …)</li>
        </ul>
      </div>

      <!-- INSTALLATION -->
      <div class="panel">
        <h2>Installation</h2>

        <div class="install-grid">
          <div>
            <h3>Composer</h3>
            <div class="code-card">
              <div class="code-card-head"><span>bash</span></div>
              <pre class="line-numbers language-bash"><code class="language-bash">composer require ndtan/dbf</code></pre>
            </div>

            <div class="code-card">
              <div class="code-card-head"><span>PHP</span></div>
              <pre class="line-numbers language-php"><code class="language-php">&lt;?php
require __DIR__ . '/vendor/autoload.php';

use ndtan\DBF;

$db = new DBF([
  'type'     =&gt; 'mysql',
  'host'     =&gt; '127.0.0.1',
  'database' =&gt; 'app',
  'username' =&gt; 'root',
  'password' =&gt; 'secret',
  'charset'  =&gt; 'utf8mb4',
]);</code></pre>
            </div>
          </div>

          <div>
            <h3>Single file</h3>
            <div class="code-card">
              <div class="code-card-head"><span>PHP</span></div>
              <pre class="line-numbers language-php"><code class="language-php">&lt;?php
require __DIR__ . '/DBF.php';

$db = new ndtan\DBF('mysql://root:secret@127.0.0.1/app?charset=utf8mb4');</code></pre>
            </div>
          </div>
        </div>
      </div>

      <!-- QUICK START -->
      <div class="panel">
        <h2>Quick start</h2>
        <div class="code-card">
          <div class="code-card-head"><span>PHP</span></div>
          <pre class="line-numbers language-php"><code class="language-php">&lt;?php
use ndtan\DBF;

// 1) Connect (SQLite demo)
$db = new DBF('sqlite::memory:');

// 2) Schema (SQLite)
$db-&gt;raw("CREATE TABLE users (id INTEGER PRIMARY KEY, email TEXT, status TEXT, deleted_at TEXT)");

// 3) Insert
$db-&gt;table('users')-&gt;insertMany([
  ['email' =&gt; 'p1@ndtan.net', 'status' =&gt; 'active'],
  ['email' =&gt; 'p2@ndtan.net', 'status' =&gt; 'vip'],
]);

// 4) Select with builder
$rows = $db-&gt;table('users')
  -&gt;select(['id','email'])
  -&gt;where(['status' =&gt; 'active'])
  -&gt;orderBy('id', 'desc')
  -&gt;limit(20)
  -&gt;get();

// 5) Update + Soft delete
$id = $db-&gt;table('users')-&gt;insert(['email' =&gt; 'a@ndtan.net', 'status' =&gt; 'vip']);
$db-&gt;table('users')-&gt;where('id','=', $id)-&gt;update(['status' =&gt; 'active']);
$db-&gt;table('users')-&gt;where('id','=', $id)-&gt;delete(); // soft delete if enabled

// 6) Transaction with retry
$db-&gt;tx(function(DBF $tx){
  $oid = $tx-&gt;table('orders')-&gt;insert(['user_id' =&gt; 10, 'total' =&gt; 200]);
  $tx-&gt;table('order_items')-&gt;insert(['order_id' =&gt; $oid, 'sku' =&gt; 'A', 'qty' =&gt; 1]);
}, attempts: 3);

// 7) Upsert
$db-&gt;table('users')-&gt;upsert(
  ['email' =&gt; 'a@ndtan.net', 'status' =&gt; 'vip'],
  conflict: ['email'],
  updateColumns: ['status']
);</code></pre>
        </div>
      </div>

    </div>
  </section>

</main>

<footer class="site-footer">
  <div class="wrap">
    <p>Made with <span class="heart">❤</span> by <a href="https://nguyenduytan.com" target="_blank" rel="noopener">Tony Nguyen</a></p>
  </div>
</footer>

<!-- Prism order: core → clike → markup → markup-templating → php; then plugins -->
<script src="https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-core.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-clike.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-markup.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-markup-templating.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-php.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1/plugins/line-numbers/prism-line-numbers.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1/plugins/toolbar/prism-toolbar.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js"></script>
<script src="/assets/js/docs.js?v=3" defer></script>
</body>
</html>
