承接 nilsframework/nils-orm 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

nilsframework/nils-orm

最新稳定版本:1.0.0

Composer 安装命令:

composer require nilsframework/nils-orm

包简介

ORM léger pour NilsFramework — CRUD complet, relations, validation, eager loading et pagination.

README 文档

README

ORM léger pour NilsFramework — CRUD complet, relations, validation, eager loading et pagination.

📋 Table des matières

Installation

composer require nilsframework/nils-orm

nilsframework/nils-database est installé automatiquement comme dépendance. Si vous utilisez déjà nilsframework/nils et nilsframework/nils-database dans votre projet, nils-orm s'y intègre sans conflit.

Avec le framework complet

# Installation complète recommandée
composer require nilsframework/nils
composer require nilsframework/nils-database
composer require nilsframework/nils-orm

Standalone

# nils-orm seul — nils-database est tiré automatiquement
composer require nilsframework/nils-orm

Créer un modèle

use core\Modele;

class Groupe extends Modele
{
    protected static string $table      = 'tnt_groupes';
    protected static string $primaryKey = 'id';

    protected static array $guarded  = ['created_at', 'updated_at'];
    protected static array $hidden   = [];
    protected static array $visible  = [];

    protected static array $schema = [
        'nom' => [
            'type'     => 'string',
            'required' => true,
            'min'      => 2,
            'max'      => 100,
            'messages' => [
                'required' => "Le nom du groupe est requis.",
            ],
        ],
        'montant_cotisation' => [
            'type'     => 'float',
            'required' => true,
            'min'      => 1,
        ],
        'frequence_jours' => [
            'type'     => 'int',
            'required' => true,
        ],
        'date_debut' => [
            'type'     => 'date',
            'required' => true,
        ],
        'description' => [
            'type'     => 'string',
            'required' => false,
        ],
    ];

    public function participations(): array
    {
        return $this->hasMany(Participation::class, 'groupe_id');
    }

    public function cycles(): array
    {
        return $this->hasMany(Cycle::class, 'groupe_id', orderBy: 'numero ASC');
    }

    public function admin(): mixed
    {
        return $this->belongsTo(Admin::class, 'admin_id');
    }
}

Les champs présents en base de données mais absents du $schema sont acceptés sans erreur.

Schema de validation

Chaque champ du schema accepte les règles suivantes :

RègleTypeDescription
typestringstring, int, float, bool, date, datetime, enum
requiredboolChamp obligatoire
minint/floatLongueur min (string) ou valeur min (numérique)
maxint/floatLongueur max (string) ou valeur max (numérique)
emailboolValidation email
uniqueboolUnicité en base de données
hashboolHash automatique bcrypt
defaultmixedValeur par défaut si absent
valuesarrayValeurs autorisées pour enum
messagesarrayMessages d'erreur personnalisés
protected static array $schema = [
    'email' => [
        'type'     => 'string',
        'required' => true,
        'email'    => true,
        'unique'   => true,
        'messages' => [
            'required' => "L'email est requis.",
            'invalid'  => "L'email est invalide.",
            'unique'   => "Cet email est déjà utilisé.",
        ],
    ],
    'password' => [
        'type'     => 'string',
        'required' => true,
        'min'      => 8,
        'hash'     => true,
    ],
    'role' => [
        'type'   => 'enum',
        'values' => ['admin', 'membre', 'moderateur'],
    ],
    'actif' => [
        'type'    => 'bool',
        'default' => true,
    ],
    'date_naissance' => [
        'type' => 'date', // Y-m-d
    ],
    'created_at' => [
        'type' => 'datetime', // Y-m-d H:i:s
    ],
];

Visibilité des champs

$hidden — masquer des champs dans toArray()

protected static array $hidden = ['password', 'remember_token'];

$visible — n'afficher que ces champs dans toArray()

protected static array $visible = ['id', 'nom', 'email'];
// Si $visible est défini → seuls ces champs apparaissent (prioritaire sur $hidden)

$guarded — champs jamais envoyés en INSERT/UPDATE

protected static array $guarded = ['created_at', 'updated_at'];
// La clé primaire est toujours exclue automatiquement

$fillable — champs autorisés en écriture

protected static array $fillable = ['nom', 'email', 'password'];
// Si vide → tous les champs sauf $guarded et la PK sont autorisés

CRUD

get()

Récupère un élément par ID ou une liste filtrée.

// Par ID — retourne l'objet ou lève NotFoundException
$groupe = Groupe::get(1);

// Tous les enregistrements
$groupes = Groupe::get();

// Avec ORDER BY
$groupes = Groupe::get(null, 'created_at DESC');

// Avec LIMIT
$groupes = Groupe::get(null, 'created_at DESC', 5);

// Avec filtres
$groupes = Groupe::get(['admin_id' => 3]);

post()

Crée un nouvel enregistrement avec validation complète.

$groupe = Groupe::post([
    'admin_id'           => 1,
    'nom'                => 'Tontine 2024',
    'montant_cotisation' => 5000,
    'frequence_jours'    => 30,
    'date_debut'         => '2024-01-01',
    'description'        => 'Notre tontine annuelle',
]);

echo $groupe->id;  // ID généré automatiquement
echo $groupe->nom; // "Tontine 2024"

put()

Remplace entièrement un enregistrement existant.

$groupe = Groupe::put(1, [
    'nom'                => 'Nouveau nom',
    'montant_cotisation' => 10000,
    'frequence_jours'    => 15,
    'date_debut'         => '2024-06-01',
]);

patch()

Met à jour partiellement — valide uniquement les champs fournis.

// Un seul champ
$groupe = Groupe::patch(1, ['nom' => 'Nom modifié']);

// Plusieurs champs
$groupe = Groupe::patch(1, [
    'montant_cotisation' => 7500,
    'description'        => 'Description mise à jour',
]);

delete()

Supprime et retourne l'objet supprimé.

$groupe = Groupe::delete(1);
echo $groupe->nom; // "Tontine 2024" — l'objet est retourné avant suppression

Filtres avancés

// Égalité
$groupes = Groupe::get(['admin_id' => 5]);

// Valeur nulle
$groupes = Groupe::get(['description' => null]);
// → WHERE description IS NULL

// LIKE
$groupes = Groupe::get(['nom_like' => 'tontine']);
// → WHERE nom LIKE '%tontine%'

// Min / Max
$groupes = Groupe::get(['montant_cotisation_min' => 1000]);
// → WHERE montant_cotisation >= 1000

$groupes = Groupe::get(['montant_cotisation_max' => 10000]);
// → WHERE montant_cotisation <= 10000

// Combinés
$groupes = Groupe::get([
    'admin_id'               => 3,
    'nom_like'               => 'ton',
    'montant_cotisation_min' => 1000,
    'montant_cotisation_max' => 50000,
], 'created_at DESC');

Pagination

$result = Groupe::get([
    'admin_id'   => 3,
    'pagination' => true,
    'page'       => 1,
    'limit'      => 10,
], 'created_at DESC');

// Résultat
// [
//   'total' => 45,
//   'page'  => 1,
//   'limit' => 10,
//   'pages' => 5,
//   'items' => [ Groupe, Groupe, ... ]
// ]

foreach ($result['items'] as $groupe) {
    echo $groupe->nom;
}

Relations

hasOne

Ce modèle possède un seul autre modèle.

// Dans le modèle Admin
public function session(): mixed
{
    return $this->hasOne(AdminSession::class, 'admin_id');
}

// Utilisation
$admin   = Admin::get(1);
$session = $admin->session();

hasMany

Ce modèle possède plusieurs autres modèles.

// Dans le modèle Groupe
public function participations(): array
{
    return $this->hasMany(Participation::class, 'groupe_id');
}

public function cycles(): array
{
    return $this->hasMany(Cycle::class, 'groupe_id', orderBy: 'numero ASC');
}

// Utilisation
$groupe         = Groupe::get(1);
$participations = $groupe->participations();
$cycles         = $groupe->cycles();

belongsTo

Ce modèle appartient à un autre modèle.

// Dans le modèle Participation
public function groupe(): mixed
{
    return $this->belongsTo(Groupe::class, 'groupe_id');
}

public function utilisateur(): mixed
{
    return $this->belongsTo(Utilisateur::class, 'utilisateur_id');
}

// Utilisation
$participation = Participation::get(1);
$groupe        = $participation->groupe();
$utilisateur   = $participation->utilisateur();

belongsToMany

Relation N-N via table pivot.

// Dans le modèle Utilisateur
public function groupes(): array
{
    return $this->belongsToMany(
        Groupe::class,
        'tnt_participations', // table pivot
        'utilisateur_id',     // FK locale dans le pivot
        'groupe_id'           // FK liée dans le pivot
    );
}

// Utilisation
$utilisateur = Utilisateur::get(1);
$groupes     = $utilisateur->groupes();

Eager Loading

Charge les relations en même temps que l'objet principal.

// Charger un groupe avec ses participations et cycles
$groupe = Groupe::with(['participations', 'cycles'])->get(1);

// Les relations sont accessibles via toArray(true)
$data = $groupe->toArray(true);
// [
//   'id'             => 1,
//   'nom'            => 'Tontine 2024',
//   'participations' => [ [...], [...] ],
//   'cycles'         => [ [...], [...] ],
// ]

// Ou directement
$groupe->participations; // tableau de Participation
$groupe->cycles;         // tableau de Cycle

toArray()

$groupe = Groupe::get(1);

// Sans relations
$data = $groupe->toArray();
// ['id' => 1, 'nom' => 'Tontine 2024', ...]

// Avec relations chargées (eager ou lazy)
$groupe->chargerRelations(['participations', 'cycles']);
$data = $groupe->toArray(true);
// ['id' => 1, 'nom' => '...', 'participations' => [...], 'cycles' => [...]]

save()

Sauvegarde manuellement un objet — INSERT si pas de PK, UPDATE sinon.

// Modifier un attribut et sauvegarder
$groupe = Groupe::get(1);
$groupe->nom = "Nouveau nom";
$groupe->save();

// Créer manuellement
$groupe = new Groupe();
$groupe->hydrater([
    'admin_id'           => 1,
    'nom'                => 'Tontine manuelle',
    'montant_cotisation' => 5000,
    'frequence_jours'    => 30,
    'date_debut'         => '2024-01-01',
]);
$groupe->save();
echo $groupe->id; // ID généré

Licence

MIT — © NilsFramework

nilsframework/nils-orm 适用场景与选型建议

nilsframework/nils-orm 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 11 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 04 月 19 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 nilsframework/nils-orm 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 nilsframework/nils-orm 我们能提供哪些服务?
定制开发 / 二次开发

基于 nilsframework/nils-orm 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 11
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 46
  • 依赖项目数: 4
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-04-19