Quick Start#

This section builds a minimal flow: connect, write, read, and query with conditions. It uses SQLite in-memory so you can run it without external setup.

1. Configure a Connection#

<?php
declare(strict_types=1);

use Infocyph\DBLayer\DB;

require __DIR__ . '/../vendor/autoload.php';

DB::addConnection([
    'driver' => 'sqlite',
    'database' => ':memory:',
]);

2. Create Schema and Seed Data#

DB::statement(
    'create table users (
        id integer primary key autoincrement,
        email text not null unique,
        name text not null,
        active integer not null default 1
    )',
);

DB::table('users')->insert([
    ['email' => '[email protected]', 'name' => 'Alice', 'active' => 1],
    ['email' => '[email protected]', 'name' => 'Bob', 'active' => 0],
]);

3. Read with Query Builder#

$active = DB::table('users')
    ->select('id', 'email', 'name')
    ->where('active', '=', 1)
    ->orderBy('id')
    ->get();

4. Write with Transaction Safety#

DB::transaction(function (): void {
    DB::table('users')->insert([
        'email' => '[email protected]',
        'name' => 'Carol',
        'active' => 1,
    ]);
});

5. Read with Repository API#

$users = DB::repository('users');
$one = $users->find(1);

6. Pick the Right API for New Work#

Use this rule of thumb:

  • enter through DB first, then decide if you stay on facade methods or branch to builder/repository

  • DB for infrastructure concerns (transactions, retries, telemetry, pooling).

  • DB::table() / QueryBuilder for ad-hoc SQL shape.

  • DB::repository() for reusable table policies.

DB::transaction(function (): void {
    $users = DB::repository('users');
    $firstActive = $users->first(fn ($q) => $q->where('active', '=', 1));

    if ($firstActive !== null) {
        DB::table('users')
            ->where('id', '=', $firstActive['id'])
            ->update(['name' => 'Updated in TX']);
    }
});

What To Do Next#

  • Move to choosing-api for a full scenario matrix.

  • Move to table-repository for repository-oriented static workflows (without ORM).

  • Move to examples-cookbook for copy-ready snippets by use case.

  • Move to configuration for multi-connection and security options.

  • Move to connections for replica and pooling behavior.

  • Move to query-builder and repository for advanced usage patterns.

Copy-Paste Single-File Examples#

SQLite (local/dev)#

<?php
declare(strict_types=1);

use Infocyph\DBLayer\DB;

require __DIR__ . '/vendor/autoload.php';

DB::addConnection([
    'driver' => 'sqlite',
    'database' => ':memory:',
], 'sqlite');

DB::statement('create table users (id integer primary key autoincrement, name text not null)', [], 'sqlite');
DB::table('users', 'sqlite')->insert(['name' => 'Alice']);

$rows = DB::table('users', 'sqlite')->select('id', 'name')->get();
var_export($rows);

MySQL (single file)#

<?php
declare(strict_types=1);

use Infocyph\DBLayer\DB;

require __DIR__ . '/vendor/autoload.php';

DB::addConnection([
    'driver' => 'mysql',
    'host' => '127.0.0.1',
    'port' => 3306,
    'database' => 'app',
    'username' => 'app',
    'password' => 'secret',
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
], 'mysql');

$row = DB::selectOne('select 1 as ok', [], 'mysql');
var_export($row);

PostgreSQL (single file)#

<?php
declare(strict_types=1);

use Infocyph\DBLayer\DB;

require __DIR__ . '/vendor/autoload.php';

DB::addConnection([
    'driver' => 'pgsql',
    'host' => '127.0.0.1',
    'port' => 5432,
    'database' => 'app',
    'username' => 'app',
    'password' => 'secret',
    'charset' => 'utf8',
    'schema' => 'public',
    'sslmode' => 'require',
], 'pgsql');

$row = DB::selectOne('select 1 as ok', [], 'pgsql');
var_export($row);