hstanleycrow/easyphpdbcore

Lightweight PDO-based database layer with a simple CRUD model for PHP.

Maintainers

Package info

github.com/hstanleycrow/EasyPHPDBCore

pkg:composer/hstanleycrow/easyphpdbcore

Transparency log

Statistics

Installs: 5

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-07-12 00:36 UTC

This package is auto-updated.

Last update: 2026-07-12 00:38:33 UTC


README

English | Español

EasyPHPDBCore

Lightweight PDO-based database layer for PHP, with a simple CRUD Model and prepared statements everywhere.

Requirements

  • PHP 8.2 or higher
  • Composer
  • PDO with the pdo_mysql driver (for the MySQL/MariaDB connection)

Runtime dependency: psr/log. A PSR-3 logger is optional; without one, errors are simply thrown as exceptions.

Installation

composer require hstanleycrow/easyphpdbcore

Quick example

use hstanleycrow\EasyPHPDBCore\Model;
use hstanleycrow\EasyPHPDBCore\Connection\MySQLEnvConfig;
use hstanleycrow\EasyPHPDBCore\Connection\MySQLPDOConnection;
use hstanleycrow\EasyPHPDBCore\Connection\MySQLEnvCharsetConfig;

require 'vendor/autoload.php';

// $_ENV must hold DATABASE_HOST, DATABASE_NAME, DATABASE_USERNAME,
// DATABASE_PASSWORD, DATABASE_PORT and DATABASE_CHARSET.
$connection = new MySQLPDOConnection(
    new MySQLEnvConfig($_ENV),
    new MySQLEnvCharsetConfig($_ENV)
);

class User extends Model
{
    protected ?string $table = 'users';
}

$user = new User($connection);

$id = $user->create([
    'name' => 'Harold',
    'username' => 'hstanleycrow',
    'active' => 'S',
])->lastInsertId();

$record = $user->getById($id);

$user->update(['name' => 'Harold Crow'], ['id' => $id]);

$user->delete(['id' => $id]);

Every write uses prepared statements with bound values, so array keys become column names and array values become bound parameters. Never interpolate user input into query() strings; pass it through the bindings instead.

Custom read queries

getRecords() accepts positional or named bindings:

class User extends Model
{
    protected ?string $table = 'users';

    public function getActive(): array
    {
        return $this->query('SELECT id, name FROM users WHERE active = ? ORDER BY id')
            ->getRecords(['S']);
    }
}

Optional logging

Any PSR-3 logger can be injected as the last constructor argument of the connection and the model (or the record classes). When omitted, a NullLogger is used and failures are only thrown.

$logger = new Monolog\Logger('app');
$logger->pushHandler(new Monolog\Handler\StreamHandler('php://stderr'));

$connection = new MySQLPDOConnection(new MySQLEnvConfig($_ENV), new MySQLEnvCharsetConfig($_ENV), $logger);
$user = new User($connection, $logger);

Error handling

All failures throw typed exceptions instead of printing anything:

  • hstanleycrow\EasyPHPDBCore\Exception\ConnectionException — connection/config errors.
  • hstanleycrow\EasyPHPDBCore\Exception\QueryException — query execution errors.

Both extend hstanleycrow\EasyPHPDBCore\Exception\DatabaseException, so you can catch either one specifically or the base class for all database errors.

Public API

Model

Method Description
__construct(IConnection $connection, ?LoggerInterface $logger = null) Build a model. Subclasses set protected ?string $table.
create(array $fieldsList): self Insert a row. Keys are columns, values are bound.
lastInsertId(): ?int Id generated by the last create().
query(string $query): self Set a raw SELECT to run with getRecords().
getRecords(array $bindings = []): array Run the current query and return rows as associative arrays.
getById(int|string $id): ?array SELECT * by primary key; null if not found.
update(array $updateFields, array $whereConditions): self Update rows matching all where conditions.
delete(array $whereConditions): self Delete rows matching all where conditions.
beginTransaction() / commit() / rollback(): void Transaction control on the underlying PDO.

Connection

Class Description
Connection\MySQLPDOConnection Opens a real PDO MySQL/MariaDB connection.
Connection\MockConnection No-op connection for tests.
Connection\MySQLEnvConfig / MySQLEnvCharsetConfig Read credentials/charset from an env array.
Connection\IConnection / IConfig / ICharsetConfig Interfaces to plug in your own implementations.

Record classes (used internally by Model, usable standalone)

CreateRecords, ReadRecords, UpdateRecords, DeleteRecords each expose an execute(...) method and share the same (IConnection, string $table, ?LoggerInterface) constructor shape (ReadRecords takes the query instead of a table).

Testing

composer install
composer test

The test suite runs against an in-memory SQLite database, so no MySQL server is required.

License

MIT — see LICENSE.