Skip to content

Configuration

Muhammet Şafak edited this page May 24, 2026 · 1 revision

Configuration

Every entry point — DB::createImmutable(), DB::connect(), new Database(...), Model::$credentials — accepts the same connection array shape. This page is the canonical reference for every supported field, with examples for the common drivers.

The full credential shape

[
// 1. EITHER pass a fully-formed DSN ...'dsn' => 'mysql:host=localhost;port=3306;dbname=test;charset=utf8mb4',
// 2. ... OR let the package build one from the parts:'driver' => 'mysql', // mysql | pgsql | sqlite | any PDO driver name'host' => '127.0.0.1',
'port' => 3306,
'database' => 'test',
'username' => 'root',
'password' => '',
// Connection-level character set (applied via SET NAMES after connect, MySQL only)'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
// PDO options (passed to `new PDO(..., ..., ..., $options)`)'options' => [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
],
// Options forwarded to every prepare() (e.g. PDO::ATTR_CURSOR)'queryOptions' => [],
// Optional channels'log' => null, // null | string | callable | object | Psr\Log\LoggerInterface'debug' => false, // include compiled SQL in error messages'queryLogs' => false, // start with the in-memory query log enabled
]

If both dsn and the driver-shaped fields are present, dsn wins. The other fields are still kept on the credential object for code that reads them (getDriver(), getDatabaseName()).

Per-driver examples

MySQL / MariaDB

DB::createImmutable([
'dsn' => 'mysql:host=db.internal;port=3306;dbname=app;charset=utf8mb4',
'username' => 'app',
'password' => getenv('DB_PASSWORD') ?: '',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
]);

Equivalent without a DSN:

DB::createImmutable([
'driver' => 'mysql',
'host' => 'db.internal',
'port' => 3306,
'database' => 'app',
'username' => 'app',
'password' => getenv('DB_PASSWORD') ?: '',
'charset' => 'utf8mb4',
]);

PostgreSQL

DB::createImmutable([
'driver' => 'pgsql',
'host' => 'pg.internal',
'port' => 5432,
'database' => 'app',
'username' => 'app',
'password' => getenv('DB_PASSWORD') ?: '',
'charset' => 'UTF8',
]);

charset and collation apply only to MySQL (the package issues SET NAMES … COLLATE … after connect). On PostgreSQL the encoding comes from the cluster / database itself; leave the fields default.

SQLite — file

DB::createImmutable([
'driver' => 'sqlite',
'database' => __DIR__ . '/data/app.sqlite',
'charset' => '',
]);

SQLite — in-memory

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

Each PDO handle opens its own :memory: database, so any schema / seed data must be applied to the same handle the application uses.

Field reference

FieldTypeDefaultNotes
dsnstring''Full PDO DSN. Wins over the field-shaped form when present.
driverstring'mysql'Used to pick the QueryBuilder dialect (mysql, pgsql, sqlite, generic).
hoststring'127.0.0.1'Ignored for sqlite.
portint|string3306Ignored for sqlite.
databasestring''Database name (or path for SQLite).
usernamestring|nullnull
passwordstring|nullnull
charsetstring'utf8mb4'Used in SET NAMES (MySQL only). Must match ^[A-Za-z0-9_]+$.
collationstring|nullnullAppended as COLLATE … after SET NAMES. Same identifier rule.
optionsarray<int, mixed>[]Passed to new PDO(..., ..., ..., $options).
queryOptionsarray<int, mixed>[]Passed to every prepare().
logmixednullThe log channel — see Query Logging.
debugboolfalseInclude compiled SQL in SQLExecuteException messages — dev only.
queryLogsboolfalseStart the in-memory query log already enabled.

Identifier safety

The package validates charset, collation and driver against ^[A-Za-z0-9_]+$ before interpolating them into SET NAMES — that statement cannot be parameter-bound. If you set any of those to a value containing other characters, the constructor throws InitORM\DBAL\Connection\Exceptions\ConnectionInvalidArgumentException.

The rest of the package never interpolates user input into SQL — every column / table identifier flows through driver-specific escaping (backticks on MySQL/SQLite, double quotes on PostgreSQL), and every value goes through prepared-statement parameter binding. See Reserved Keywords for a worked example.

Bootstrapping patterns

Single config file

// config/database.phpreturn [
'dsn' => sprintf('mysql:host=%s;port=%d;dbname=%s;charset=utf8mb4',
getenv('DB_HOST') ?: '127.0.0.1',
(int) (getenv('DB_PORT') ?: 3306),
getenv('DB_NAME') ?: 'app',
),
'username' => getenv('DB_USER') ?: 'root',
'password' => getenv('DB_PASSWORD') ?: '',
'debug' => filter_var(getenv('APP_DEBUG'), FILTER_VALIDATE_BOOL),
];
// public/index.php
\InitPHP\Database\DB::createImmutable(require__DIR__ . '/../config/database.php');

Dependency-injected, no facade

$db = new \InitPHP\Database\Database($credentials);
$container->set(\InitORM\Database\Interfaces\DatabaseInterface::class, $db);

This skips the static facade entirely — your code references the DatabaseInterface directly. Useful in long-lived workers where you want to test substitution without globals.

Next

Clone this wiki locally