Aller au contenu
Nibiru docsv0.9.2

Modèles

Comment Nibiru génère automatiquement les classes de modèle à partir de votre schéma de base de données et comment les étendre.

Stable Reading time ~ 3 min Edit on GitHub

La couche modèle de Nibiru est schéma-premier. Vous ne rédigez pas les modèles à la main — le framework lit votre base de données et génère une classe PHP par table à chaque démarrage.

Lorsque [GENERATOR] database = true dans votre fichier INI, le dispatcheur exécute new Model(false) à chaque requête, ce qui :

  1. Se connecte au pilote actif.
  2. Liste les tables dans la base de données configurée (information_schema.tables pour PG, SHOW TABLES pour MySQL).
  3. Pour chaque table, écrit application/model/<table>.php contenant une classe qui étend l’adaptateur Db approprié et intègre une constante TABLE décrivant les colonnes.

Le réexécution est peu coûteuse : le générateur écrase uniquement lorsque le schéma a changé, donc les modèles enregistrés conservent leurs méthodes manuscrites si vous définissez database = false après la première exécution.

[GENERATOR]
database = true ; regenerate models on each request
database.overwrite = true ; if false, generator won't touch existing files

En production, définissez database = false afin que les modèles ne soient pas régénérés à chaque requête.

Pour une table users avec les colonnes user_id, user_login, user_pass, user_email:

<?php
namespace Nibiru\Model;
use Nibiru\Adapter\MySQL\Db;
class users extends Db
{
const TABLE = [
'table' => 'users',
'field' => [
'user_id' => 'user_id',
'user_login' => 'user_login',
'user_pass' => 'user_pass',
'user_email' => 'user_email',
],
];
public function __construct() {
self::initTable(self::TABLE);
}
}

L’adaptateur Db vous offre des assistants simples CRUD via Pdo:: (ou le pilote actif) :

$users = new \Nibiru\Model\users();
// Read by primary key
$row = \Nibiru\Pdo::fetchRowInArrayById('users', ['user_id' => 42]);
// Read all
$all = \Nibiru\Pdo::fetchAll('SELECT * FROM users WHERE user_account_active = 1');
// Insert
\Nibiru\Pdo::insert('users', [
'user_login' => 'marduk',
'user_email' => 'marduk@nibiru.local',
]);
// Update
\Nibiru\Pdo::update('users',
['user_email' => 'new@nibiru.local'],
['user_id' => 42]);
// Delete
\Nibiru\Pdo::delete('users', ['user_id' => 42]);

La classe générée est une classe PHP simple — ajoutez des méthodes librement :

namespace Nibiru\Model;
use Nibiru\Adapter\MySQL\Db;
use Nibiru\Pdo;
class documentation extends Db
{
const TABLE = [
'table' => 'documentation',
'field' => [
'id' => 'id', 'title' => 'title', 'slug' => 'slug',
'content' => 'content', 'category' => 'category',
'version' => 'version',
],
];
public function __construct() { self::initTable(self::TABLE); }
public function getBySlug(string $slug): ?array {
return Pdo::fetchRowInArrayById(
self::TABLE['table'],
[self::TABLE['field']['slug'] => $slug]
) ?: null;
}
public function search(string $query): array {
$sql = 'SELECT * FROM ' . self::TABLE['table']
. ' WHERE title LIKE :q OR content LIKE :q ORDER BY title';
return Pdo::fetchAll($sql, [':q' => '%' . $query . '%']);
}
}

Si le générateur s’exécute à nouveau avec database.overwrite = true, il remplacera ce fichier. Gardez les méthodes personnalisées dans une classe enfant ou définissez database.overwrite = false après la première génération.

Pour les domaines complexes (authentification, facturation, analyse), les applications de démonstration mettent les méthodes de requête sur un plugin de module plutôt que sur le modèle brut. Le plugin détient les règles métier ; le modèle est simplement une référence typée à la table :

application/module/users/
├── plugins/
│ └── user.php # User::isAuthorized(), User::loginForm(), …
└── traits/
└── userForm.php
``````php
namespace Nibiru\Module\Users\Plugin;
use Nibiru\Model\users;
class User {
private users $usersModel;
public function __construct() { $this->usersModel = new users(); }
public function isAuthorized(): bool {
return isset($_SESSION['auth']['user_id']);
}
public function findByLogin(string $login): ?array {
return \Nibiru\Pdo::fetchRow(
'SELECT * FROM users WHERE user_login = :login',
[':login' => $login]
) ?: null;
}
}

Cela maintient les contrôleurs légers ($this->user->isAuthorized()) tout en laissant le modèle généré inchangé.

L’adaptateur généré Db est spécifique au pilote. Si vous passez de MySQL à PostgreSQL, regénérez les modèles pour qu’ils étendent la classe de base appropriée :

  • MySQL / PDO → Nibiru\Adapter\MySQL\Db
  • PostgreSQL (libpq) → Nibiru\Adapter\PostgreSQL\Db
  • ODBC → Nibiru\Adapter\Odbc\Db

Les mêmes assistants de requête, mais avec un adaptateur différent en arrière-plan.

Bases de données en lecture seule, systèmes de fournisseurs ou tout schéma que vous ne contrôlez pas : définissez database = false, rédigez manuellement des classes de modèle minimales qui correspondent aux colonnes que vous utilisez réellement, et validez-les.