ntentan/nibii is a lightweight, intuitive, and powerful Active Record-based Object-Relational Mapper (ORM) for PHP. Built as the default database interface for the ntentan framework, it can also be configured and utilized as a standalone ORM library in any PHP project.
- Active Record Pattern: Represent database tables as PHP classes extending
RecordWrapperfor seamless interaction. - Dynamic Finders and Filters: Query the database using expressive dynamic method calls like
filterByFieldName()andfetchFirstByFieldName(). - Relationship Mapping: Easy-to-use relationship configurations:
BelongsToHasManyManyHaveMany(with automatic pivot table handling)
- Built-in Validation: Easily validate model fields before saving, with support for field presence, types, and unique constraints.
- Bulk Operations: Perform batch inserts, updates, and deletes cleanly.
Install nibii via Composer:
composer require ntentan/nibiiBefore querying your models, initialize DbContext and ORMContext:
use ntentan\atiaa\DbContext;
use ntentan\atiaa\DriverFactory;
use ntentan\kaikai\Cache;
use ntentan\kaikai\backends\VolatileCache; // or any PSR-16 cache implementation
use ntentan\nibii\factories\DefaultModelFactory;
use ntentan\nibii\factories\DriverAdapterFactory;
use ntentan\nibii\factories\DefaultValidatorFactory;
use ntentan\nibii\ORMContext;
// Database connection details
$config = [
'driver' => 'postgresql', // e.g., 'postgresql', 'mysql', 'sqlite'
'host' => 'localhost',
'user' => 'db_user',
'password' => 'db_password',
'dbname' => 'my_database',
];
// Initialize database contexts
DbContext::initialize(new DriverFactory($config));
ORMContext::initialize(
new DefaultModelFactory(),
new DriverAdapterFactory($config['driver']),
new DefaultValidatorFactory(),
new Cache(new VolatileCache())
);Models in nibii extend ntentan\nibii\RecordWrapper. By default, Nibii maps the model class name to a database table (e.g., a Users model maps to the users table).
namespace App\Models;
use ntentan\nibii\RecordWrapper;
class Users extends RecordWrapper
{
// Define a belongsTo relationship to the Roles model
protected $belongsTo = ['\App\Models\Roles'];
}nibii offers several convenient ways to retrieve data.
$users = (new Users())->fetch();
foreach ($users as $user) {
echo $user->username;
}You can write custom filters using standard placeholders (? or named parameters):
// Using question mark placeholders
$user = (new Users())->filter('username = ?', 'james')->fetchFirst();
// Using named parameters
$user = (new Users())->filter('username = :username', [':username' => 'james'])->fetchFirst();Retrieve records using dynamic finder helper methods automatically generated from your column names:
// Find all users with role_id = 11 or 12
$users = (new Users())->filterByRoleId(11, 12)->fetch();
// Fetch first user matching a username
$user = (new Users())->fetchFirstWithUsername('james');Instantiate your model class, assign values as properties or array keys, and call save():
$role = new Roles();
$role->name = 'Administrator';
// Or: $role['name'] = 'Administrator';
if ($role->save()) {
echo "Saved successfully! ID: " . $role->id;
} else {
// Validation failed
print_r($role->getInvalidFields());
}$user = (new Users())->fetchFirstWithId(1);
if ($user) {
$user->username = 'new_username';
$user->save();
}You can update multiple records that match specific conditions in a single query:
// Update role_id to 15 for users matching role_id 11 or 12
(new Users())->filterByRoleId(11, 12)->update(['role_id' => 15]);You can delete a set of records directly matching a query:
// Delete all users with ID less than 3
(new Users())->filter('id < ?', 3)->delete();Configure relationships directly in your class definition properties: $belongsTo, $hasMany, and $manyHaveMany.
class Users extends RecordWrapper
{
protected $belongsTo = ['\App\Models\Roles'];
}class Roles extends RecordWrapper
{
protected $hasMany = ['\App\Models\Users'];
}class Projects extends RecordWrapper
{
public $manyHaveMany = ['\App\Models\Users'];
}This project is licensed under the MIT License. See the LICENSE file (if present) or composer.json for details.