PHPackages                             wnikk/micro-active-record - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. wnikk/micro-active-record

ActiveLibrary[Database &amp; ORM](/categories/database)

wnikk/micro-active-record
=========================

Minimal dependency - free Active Record implementation for PHP using PDO (MySQL, SQLite, PostgreSQL and more)

1.0.0(8mo ago)037MITPHPPHP &gt;=8.0

Since Oct 12Pushed 8mo agoCompare

[ Source](https://github.com/wnikk/micro-active-record)[ Packagist](https://packagist.org/packages/wnikk/micro-active-record)[ Docs](https://github.com/wnikk/micro-active-record)[ RSS](/packages/wnikk-micro-active-record/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (2)Versions (2)Used By (0)

MicroActiveRecord PDO for PHP
=============================

[](#microactiverecord-pdo-for-php)

[![License](https://camo.githubusercontent.com/b2dfc513df17dc8e41778f3562474e12b7e63a8d9f829f5b415c9947ba755d3d/68747470733a2f2f706f7365722e707567782e6f72672f776e696b6b2f6d6963726f2d6163746976652d7265636f72642f6c6963656e7365)](//packagist.org/packages/wnikk/micro-active-record)[![PHP Version Require](https://camo.githubusercontent.com/2b67eb7836842812ccc35a88c8bbc7772057172e7606ebca86290eed99888cf6/687474703a2f2f706f7365722e707567782e6f72672f776e696b6b2f6d6963726f2d6163746976652d7265636f72642f726571756972652f706870)](//packagist.org/packages/wnikk/micro-active-record)[![Latest Stable Version](https://camo.githubusercontent.com/0200422c7bddeb31163331e11dafe953bb9cba0b307ad27784728366dee4610c/68747470733a2f2f706f7365722e707567782e6f72672f776e696b6b2f6d6963726f2d6163746976652d7265636f72642f76)](//packagist.org/packages/wnikk/micro-active-record)[![Total Downloads](https://camo.githubusercontent.com/d0a49cfd5686f5a501dfa8164583cd353095b67f9a59490cc90d80b0251f1760/687474703a2f2f706f7365722e707567782e6f72672f776e696b6b2f6d6963726f2d6163746976652d7265636f72642f646f776e6c6f616473)](//packagist.org/packages/wnikk/micro-active-record)[![Dependents](https://camo.githubusercontent.com/1b8c9b00efe0d223c9b436fa7297244c2570bc15f0ffca1051b0dc6dd902cb6c/687474703a2f2f706f7365722e707567782e6f72672f776e696b6b2f6d6963726f2d6163746976652d7265636f72642f646570656e64656e7473)](https://packagist.org/packages/wnikk/micro-active-record)

A minimal, dependency - free ActiveRecord implementation for PHP using PDO. Designed for rapid development, security, and maximum portability - just drop in a single file and start working with your database safely and efficiently.

Why MicroActiveRecord?
----------------------

[](#why-microactiverecord)

- **Zero dependencies:** No frameworks or external libraries required. Just one file is enough for full functionality.
- **Security by design:** All queries use prepared statements and strict type conversion, protecting your application from SQL injection and data corruption.
- **Autonomous and flexible:** Models auto-detect table names, fields, and types. You can extend the base class or use it directly for any table.
- **Portable:** Works with MySQL, MariaDB, SQLite, PostgreSQL, MSSQL (sqlsrv/dblib), and Oracle (oci) out of the box.
- **Developer-friendly:** Fluent, chainable query builder with expressive syntax. Easy to read, easy to maintain.
- **Extensible:** Add your own models, customize logging, or override behaviors as needed.

Supported Databases and DSN Examples
------------------------------------

[](#supported-databases-and-dsn-examples)

- **MySQL:** `mysql:host=localhost;dbname=testdb;charset=utf8mb4`
- **MariaDB:** `mysql:host=localhost;dbname=testdb;charset=utf8mb4` (MariaDB is fully supported via the MySQL driver)
- **SQLite:** `sqlite:/path/to/database.db`
- **PostgreSQL:** `pgsql:host=localhost;port=5432;dbname=testdb;user=...;password=...`
- **MSSQL:** `sqlsrv:Server=localhost;Database=testdb` (Windows) or `dblib:host=localhost;dbname=testdb` (Linux)
- **Oracle:** `oci:dbname=//localhost:1521/XE;charset=UTF8`

> **Note:** For MSSQL and Oracle, the appropriate PDO driver must be installed and enabled in your PHP environment.

Getting Started
---------------

[](#getting-started)

1. **Copy the `ActiveRecord.php` and `DbConn.php` files** (and optionally `Model.php` and `ModelCollection.php`) into your project.
2. **Create and inject your PDO connection:**

```
use Wnikk\MicroActiveRecord\DbConn;
use Wnikk\MicroActiveRecord\ActiveRecord;

// Example for MySQL/MariaDB
DbConn::setConfig([
    'dsn' => 'mysql:host=localhost;dbname=testdb;charset=utf8mb4',
    'user' => 'dbuser',
    'password' => 'dbpass',
    'options' => [PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]
]);

// Or second example for MySQL/MariaDB
// $pdo = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8mb4', 'user', 'pass');
// DbConn::setPdo($pdo);

// Example for MSSQL
//$pdo = new PDO('sqlsrv:Server=localhost;Database=testdb', 'user', 'pass');
//DbConn::setPdo($pdo);

// Example for Oracle
//$pdo = new PDO('oci:dbname=//localhost:1521/XE;charset=UTF8', 'user', 'pass');
//DbConn::setPdo($pdo);

// Now you can use ActiveRecord directly:
$users = ActiveRecord::table('users')
    ->where('status', 'active')
    ->get();
```

Installation with Composer (optional)
-------------------------------------

[](#installation-with-composer-optional)

You do **not** need Composer for minimal usage - just copy the files as described above. However, if you prefer to use Composer for dependency management and autoloading, you can install MicroActiveRecord as a package:

```
composer require wnikk/micro-active-record
```

Composer will handle autoloading for you, so you can use the classes directly in your project.

Usage Examples
--------------

[](#usage-examples)

### Optional: Set PDO connection multi connections (using DbConn class)

[](#optional-set-pdo-connection-multi-connections-using-dbconn-class)

```
$pdo = new PDO('sqlite::memory:');
DbConn::setPdo($pdo, 'second_connection');

$users = ActiveRecord::table('users')
    ->setConnection('second_connection')
    ->where('status', 'active')
    ->get();
```

### Basic Select (without DbConn only ActiveRecord+PDO)

[](#basic-select-without-dbconn-only-activerecordpdo)

```
$pdo = new PDO('sqlite::memory:');
$users = ActiveRecord::setConnection($pdo)
    ->table('users')
    ->where('status', 'active')
    ->get();
```

### Select with class for table

[](#select-with-class-for-table)

```
class User extends ActiveRecord {}
$users = User::where('status', 'active')
    ->get();
```

### Insert

[](#insert)

```
$id = ActiveRecord::table('users')->insert([
    'login' => 'foo',
    'status' => 'active',
    'created_at' => time()
]);
```

### Update

[](#update)

```
ActiveRecord::table('users')
    ->where('status', 'waiting')
    ->where('profile', 'LIKE', '%confirm%')
    ->update(['status' => 'active']);
```

### Update with class for table

[](#update-with-class-for-table)

```
class User extends ActiveRecord {}
// Auto detect table name "users"
User::where('id', 5)->update(['status' => 'inactive']);
```

### Delete

[](#delete)

```
ActiveRecord::table('users')
    ->where('id', 5)
    ->delete();
```

### Complex Query

[](#complex-query)

```
$recentAdmins = ActiveRecord::table('users')
    ->where('created_at', '>=', time()-3600)
    ->whereIn('status', ['active', 'hidden'])
    ->where(function($q) {
        $q->where('type', 'root')->orWhere('type', 'admin');
    })
    ->orderBy('id', 'DESC')
    ->get();
```

### Call Raw Query

[](#call-raw-query)

```
ActiveRecord::query('CREATE INDEX idx_pname ON Users (LastName, FirstName);')->execute();
```

### Get Raw SQL

[](#get-raw-sql)

```
# For get SQL query and bindings add toSql() before any execution method
[$sql, $bindings] = ActiveRecord::table('users')
    ->where('status', 'active')
    ->toSql()
    ->get();
```

### Logging Queries

[](#logging-queries)

```
$log = [];

ActiveRecord::table('users')
    ->setLogger(function($sql, $bindings, $result) use (&$log) {
        $log[] = ['sql' => $sql, 'bindings' => $bindings, 'result' => $result];
    })
    ->where('status', 'active')
    ->get();

print_r($log);
```

### Add join with alias and select specific fields

[](#add-join-with-alias-and-select-specific-fields)

```
$users = ActiveRecord::table('users', 'u')
    ->join('profiles p', 'p.user_id = u.id', 'LEFT')
    ->where('u.status', 'active')
    ->selectRaw('u.*, p.bio')
    ->get();
```

Security and Data Safety
------------------------

[](#security-and-data-safety)

- **All input is type-checked and converted** according to the table schema. Invalid data (e.g., malformed dates, wrong enum values) throws an exception.
- **Prepared statements** are used everywhere, so user data is always safe from SQL injection.
- **Schema auto-detection** ensures that only valid fields are used in queries.

Error Handling and Diagnostics
------------------------------

[](#error-handling-and-diagnostics)

ActiveRecord provides advanced error handling and diagnostics for robust application development:

- **showException** (public property, default: `true`):

    - If `true` (default), all errors and validation issues throw exceptions as usual.
    - If `false`, no exceptions are thrown during query execution. Instead, the method returns `null` and error details are stored in the `lastErrors` property.
- **lastErrors** (public property):

    - An array containing details of the last error(s) that occurred during query execution or validation. Each error includes the type, message, code, stack trace, SQL, and bindings.
- **lastQuery** (public property):

    - An array with the last executed SQL query and its bindings, regardless of success or failure.

**Example:**

```
$ar = new ActiveRecord('users');
$ar->returnException = false;
$result = $ar->insert(['login' => null]); // login is NOT NULL
if ($result === null) {
    print_r($ar->lastErrors); // See error details
    print_r($ar->lastQuery);  // See the last attempted SQL
}
```

This makes it easy to build user-friendly APIs or admin panels where you want to handle errors gracefully without interrupting the application flow.

API Reference
-------------

[](#api-reference)

### Query Builder Methods

[](#query-builder-methods)

All methods are chainable and can be called statically (e.g., `ActiveRecord::table(...)->where(...)`) or on an instance.

- `table(string $table, ?string $alias = null)` - Set the table name (with optional alias).
- `query(?string $sql = null, ?array $params = null)` - Start a new query builder or use a raw SQL query.
- `toSql()` - Return the SQL and bindings instead of executing.
- `join($table, string $on, string $type = 'INNER', ?string $alias = null)` - Add a JOIN clause.
- `whereRaw(string $expression, array $bindings = [], string $boolean = 'AND')` - Add a raw SQL WHERE condition.
- `where(string|array|ArrayObject|callable $field, string|null $op = null, mixed|null $value = null)` - Add a WHERE condition.
- `orWhere(string|callable $field, string|null $op = null, mixed|null $value = null)` - Add an OR WHERE condition.
- `whereIn(string $field, array $values)` - Add a WHERE IN condition.
- `orWhereIn(string $field, array $values)` - Add an OR WHERE IN condition.
- `whereNull(string $field)` - Add a WHERE ... IS NULL condition.
- `whereNotNull(string $field)` - Add a WHERE ... IS NOT NULL condition.
- `select(string $fields)` - Set SELECT fields (comma-separated or '\*').
- `selectRaw(string $expression)` - Set a raw SELECT expression.
- `orderBy(string $field, string $direction = 'ASC')` - Set ORDER BY clause.
- `orderByRaw(string $expression)` - Set a raw ORDER BY clause.
- `groupBy(string|array $fields)` - Set GROUP BY clause.
- `groupByRaw(string $expression)` - Set a raw GROUP BY clause.
- `limit(int $limit, int $offsetOrPage = 0, bool $pageMode = false)` - Set LIMIT and OFFSET (or page mode).
- `having($field, $op = null, $value = null)` - Add a HAVING condition.
- `orHaving($field, $op = null, $value = null)` - Add an OR HAVING condition.
- `havingRaw(string $expression, array $bindings = [], string $boolean = 'AND')` - Add a raw HAVING condition.

### Execution Methods

[](#execution-methods)

- `get()` - Get all results as an ArrayObject (or custom collection class).
- `getOne()` - Get a single value (first row, first column).
- `getLine()` - Get the first row as ArrayObject (or null).
- `find($id)` - Find a record by primary key value.
- `insert(array $data)` - Insert a row and return the last insert id.
- `update(array|ArrayObject $data)` - Update rows matching the current query.
- `delete()` - Delete rows matching the current query.
- `execute()` - Execute a raw SQL query with optional bindings.
- `createTable(bool $ifNotExists = false)` - Create a table in the database based on the current schema.

### Utility Methods

[](#utility-methods)

- `setConnection(PDO $conn)` - Set a PDO connection directly.
- `setLogger(callable $logger)` - Set a logger callback for queries and results.
- `setRowClass(string $class)` - Set the class for one row result.
- `setCollectionClass(string $class)` - Set the class for a collection of rows.

Advanced Usage
--------------

[](#advanced-usage)

### Custom Models

[](#custom-models)

You can extend `ActiveRecord` or `Model` to add business logic, validation, or computed properties:

```
use Wnikk\MicroActiveRecord\ActiveRecord;
class User extends ActiveRecord {
    // Add custom methods or override behaviors
}
```

### Using with Different Databases

[](#using-with-different-databases)

Just change the DSN in your config or inject a different PDO. All features work with MySQL, MariaDB, SQLite, PostgreSQL, MSSQL (sqlsrv/dblib), and Oracle (oci).

### Schema Definition

[](#schema-definition)

You can define columns and types in your model for stricter validation:

```
class User extends ActiveRecord {
    protected string $table = 'global_users';
    protected array $columns = [
        'id' => 'int primary key auto_increment',
        'login' => 'varchar(255) not null',
        'status' => "enum('active','inactive') not null default 'active'",
        'created_at' => 'datetime not null',
    ];
}
```

FAQ
---

[](#faq)

**Q: Can I use this in production?**
A: Yes! It is designed for safety and performance. All queries are parameterized and types are checked.

**Q: What if I need more features?**
A: You can extend the base class or add your own methods. The code is simple and well-documented.

**Q: Is it compatible with frameworks?**
A: Yes, but it is designed to be framework-agnostic. You can use it anywhere PHP and PDO are available.

###  Health Score

30

—

LowBetter than 62% of packages

Maintenance59

Moderate activity, may be stable

Popularity7

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

265d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1561751?v=4)[Nikolay Lagun](/maintainers/Nikolya)[@Nikolya](https://github.com/Nikolya)

---

Top Contributors

[![wnikk](https://avatars.githubusercontent.com/u/119752633?v=4)](https://github.com/wnikk "wnikk (9 commits)")

---

Tags

phpmicrodatabaseormmysqlsqlitepostgresqldbalpdomssqloracledbactive-recordminimalMariamar

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/wnikk-micro-active-record/health.svg)

```
[![Health](https://phpackages.com/badges/wnikk-micro-active-record/health.svg)](https://phpackages.com/packages/wnikk-micro-active-record)
```

###  Alternatives

[doctrine/dbal

Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.

9.7k605.0M6.8k](/packages/doctrine-dbal)[dibi/dibi

Dibi is Database Abstraction Library for PHP

5014.0M134](/packages/dibi-dibi)[tommyknocker/pdo-database-class

Framework-agnostic PHP database library with unified API for MySQL, MariaDB, PostgreSQL, SQLite, MSSQL, and Oracle. Query Builder, caching, sharding, window functions, CTEs, JSON, migrations, ActiveRecord, CLI tools, AI-powered analysis. Zero external dependencies.

846.1k](/packages/tommyknocker-pdo-database-class)[cycle/database

DBAL, schema introspection, migration and pagination

71777.8k53](/packages/cycle-database)[ramadan/easy-model

A Laravel package for enjoyably managing database queries.

111.6k](/packages/ramadan-easy-model)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
