> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Eloquent Bootable Traits

> Plongée en profondeur dans le mécanisme d'auto-boot des traits d'Eloquent. Apprenez les conventions de nommage bootXxx() et initializeXxx() et comment utiliser les PHP Attributes pour un enregistrement explicite — un pattern essentiel pour le développement de packages.

## 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`.

```mermaid theme={null}
sequenceDiagram
    participant App as Application
    participant Model as Eloquent Model
    participant Trait as Trait

    App->>Model: new Post() ou Post::find()
    Model->>Model: bootIfNotBooted()
    Model->>Trait: bootXxx() (une fois par classe)
    Model->>Model: initializeTraits()
    Model->>Trait: initializeXxx() (par instance)
    Model-->>App: instance du modèle
```

***

## boot vs. initialize

|                       | `bootXxx()`                                                       | `initializeXxx()`                                               |
| --------------------- | ----------------------------------------------------------------- | --------------------------------------------------------------- |
| **Moment de l'appel** | Une seule fois lors du premier boot de la classe du modèle        | À chaque création d'instance                                    |
| **Type de méthode**   | `static`                                                          | Méthode d'instance                                              |
| **Usage typique**     | Enregistrer des écouteurs d'événements, ajouter des global scopes | Dé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.

```php theme={null}
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 :

```php theme={null}
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.

```php theme={null}
namespace App\Models\Concerns;

trait HasDefaultStatus
{
    public function initializeHasDefaultStatus(): void
    {
        $this->attributes['status'] ??= 'draft';
    }
}
```

La fusion dynamique des casts est un autre usage courant :

```php theme={null}
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.

| Attribute       | Rô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      |

```php theme={null}
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;
    }
}
```

<Info>
  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.
</Info>

***

## Exemples pratiques

### Ajout automatique d'un global scope

```php theme={null}
trait HasTenant
{
    public static function bootHasTenant(): void
    {
        static::addGlobalScope(new TenantScope);
    }
}
```

### Fusion de casts par défaut

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

### Archivage automatique lors de la suppression

```php theme={null}
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 :

| Trait         | Méthode             | Ce qu'il fait                                  |
| ------------- | ------------------- | ---------------------------------------------- |
| `SoftDeletes` | `bootSoftDeletes()` | Enregistre le global scope `SoftDeletingScope` |
| `HasUlids`    | `bootHasUlids()`    | Définit un ULID lors de l'événement `creating` |
| `HasUuids`    | `bootHasUuids()`    | 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 :

```php theme={null}
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é

| Pattern                   | Comment le définir                   | Quand l'utiliser                      |
| ------------------------- | ------------------------------------ | ------------------------------------- |
| Boot de classe            | `static bootXxx()` ou `#[Boot]`      | Écouteurs d'événements, global scopes |
| Initialisation d'instance | `initializeXxx()` 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.


## Related topics

- [Trait Conditionable](/fr/advanced/conditionable.md)
- [Trait Dumpable](/fr/advanced/dumpable.md)
- [Factories Eloquent](/fr/eloquent-factories.md)
- [Trait ForwardsCalls](/fr/advanced/forwards-calls.md)
- [Scopes Eloquent](/fr/advanced/eloquent-scopes.md)
