Passer au contenu principal

Vue d’ensemble

Chaque fois qu’un modèle Eloquent est instancié, il exécute deux phases : boot (une fois par classe) et initialize (une fois par instance). Lorsque vous définissez des méthodes spécifiques dans un trait, Eloquent les découvre et les appelle automatiquement. Il suffit d’ajouter le trait au modèle. Laravel lui-même utilise abondamment ce pattern dans des traits tels que SoftDeletes, HasUuids et HasUlids.

boot vs. initialize

bootXxx()initializeXxx()
Moment de l’appelUne seule fois lors du premier boot de la classe du modèleÀ chaque création d’instance
Type de méthodestaticMéthode d’instance
Usage typiqueEnregistrer des écouteurs d’événements, ajouter des global scopesDéfinir des valeurs d’attributs par défaut, fusionner des casts

Conventions de nommage

bootXxx()

Définissez une méthode static préfixée par boot suivi du nom de base de la classe du trait. Eloquent l’appelle une seule fois par cycle de vie de la classe.
namespace App\Models\Concerns;

trait HasSlug
{
    public static function bootHasSlug(): void
    {
        static::creating(function ($model) {
            if (empty($model->slug)) {
                $model->slug = str($model->name)->slug()->toString();
            }
        });
    }
}
Utilisation du trait dans un modèle :
use App\Models\Concerns\HasSlug;

class Article extends Model
{
    use HasSlug;
    // bootHasSlug() est appelée automatiquement
}

initializeXxx()

Définissez une méthode d’instance préfixée par initialize suivi du nom de base de la classe du trait. Eloquent l’appelle à chaque création d’une nouvelle instance.
namespace App\Models\Concerns;

trait HasDefaultStatus
{
    public function initializeHasDefaultStatus(): void
    {
        $this->attributes['status'] ??= 'draft';
    }
}
La fusion dynamique des casts est un autre usage courant :
trait HasMetadata
{
    public function initializeHasMetadata(): void
    {
        $this->mergeCasts([
            'metadata' => 'array',
        ]);
    }
}

PHP Attributes

Depuis Laravel 11, vous pouvez utiliser les PHP Attributes au lieu de vous appuyer sur les conventions de nommage.
AttributeRôle
#[Boot]Marque une méthode statique à exécuter une fois au boot de la classe
#[Initialize]Marque une méthode d’instance à exécuter à chaque instanciation
use Illuminate\Database\Eloquent\Attributes\Boot;
use Illuminate\Database\Eloquent\Attributes\Initialize;

trait HasAuditLog
{
    #[Boot]
    public static function registerAuditListeners(): void
    {
        static::created(function ($model) {
            AuditLog::record('created', $model);
        });

        static::updated(function ($model) {
            AuditLog::record('updated', $model);
        });
    }

    #[Initialize]
    public function setAuditDefaults(): void
    {
        $this->attributes['audit_enabled'] ??= true;
    }
}
L’utilisation des PHP Attributes libère les noms de vos méthodes de la contrainte liée au nom du trait. Vous pouvez également définir plusieurs méthodes #[Boot] ou #[Initialize] au sein d’un même trait.

Exemples pratiques

Ajout automatique d’un global scope

trait HasTenant
{
    public static function bootHasTenant(): void
    {
        static::addGlobalScope(new TenantScope);
    }
}

Fusion de casts par défaut

trait HasJsonSettings
{
    public function initializeHasJsonSettings(): void
    {
        $this->mergeCasts([
            'settings' => 'array',
        ]);
    }
}

Archivage automatique lors de la suppression

trait Archivable
{
    #[Boot]
    public static function bootArchivable(): void
    {
        static::deleting(function ($model) {
            Archive::store($model->toArray());
        });
    }
}

Exemples dans le framework

Les propres traits de Laravel illustrent clairement ce pattern :
TraitMéthodeCe qu’il fait
SoftDeletesbootSoftDeletes()Enregistre le global scope SoftDeletingScope
HasUlidsbootHasUlids()Définit un ULID lors de l’événement creating
HasUuidsbootHasUuids()Définit un UUID lors de l’événement creating
Lire ces implémentations est une excellente façon de comprendre le pattern en profondeur.

Points d’attention

Réinitialiser les modèles bootés dans les tests

Puisque boot* ne s’exécute qu’une seule fois par classe, les tests qui modifient le comportement des modèles peuvent nécessiter de réinitialiser le cache de boot :
protected function tearDown(): void
{
    Model::clearBootedModels();
    parent::tearDown();
}

Ordre d’exécution

Lorsqu’un modèle utilise plusieurs traits, bootXxx() et initializeXxx() sont appelées dans l’ordre de résolution des traits par PHP (ordre de déclaration). Soyez attentif à l’ordre lorsque les traits dépendent les uns des autres.

Résumé

PatternComment le définirQuand l’utiliser
Boot de classestatic bootXxx() ou #[Boot]Écouteurs d’événements, global scopes
Initialisation d’instanceinitializeXxx() ou #[Initialize]Valeurs par défaut, casts dynamiques
Implémenter bootXxx() et initializeXxx() dans un trait vous permet d’injecter du comportement dans n’importe quel modèle Eloquent avec une seule instruction use — le pattern incontournable pour les auteurs de packages.
Dernière modification le 13 juillet 2026