Zum Hauptinhalt springen

Überblick

Jedes Mal, wenn ein Eloquent-Modell instanziiert wird, durchläuft es zwei Phasen: boot (einmal pro Klasse) und initialize (einmal pro Instanz). Wenn Sie bestimmte Methoden in einem Trait definieren, erkennt Eloquent diese automatisch und ruft sie auf. Es genügt, den Trait dem Modell hinzuzufügen. Laravel selbst nutzt dieses Muster ausgiebig in Traits wie SoftDeletes, HasUuids und HasUlids.

boot vs. initialize

bootXxx()initializeXxx()
Wann aufgerufenEinmal, wenn die Modellklasse erstmals bootetBei jeder Instanzerstellung
MethodentypstaticInstanzmethode
Typische VerwendungEvent-Listener registrieren, globale Scopes hinzufügenStandard-Attributwerte setzen, Casts zusammenführen

Namenskonventionen

bootXxx()

Definieren Sie eine static Methode mit dem Präfix boot, gefolgt vom Klassenbasisnamen des Traits. Eloquent ruft sie einmal pro Klassen-Lebenszyklus auf.
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();
            }
        });
    }
}
Verwendung des Traits in einem Modell:
use App\Models\Concerns\HasSlug;

class Article extends Model
{
    use HasSlug;
    // bootHasSlug() wird automatisch aufgerufen
}

initializeXxx()

Definieren Sie eine Instanzmethode mit dem Präfix initialize, gefolgt vom Klassenbasisnamen des Traits. Eloquent ruft sie bei jeder Erstellung einer neuen Instanz auf.
namespace App\Models\Concerns;

trait HasDefaultStatus
{
    public function initializeHasDefaultStatus(): void
    {
        $this->attributes['status'] ??= 'draft';
    }
}
Das dynamische Zusammenführen von Casts ist ein weiterer häufiger Anwendungsfall:
trait HasMetadata
{
    public function initializeHasMetadata(): void
    {
        $this->mergeCasts([
            'metadata' => 'array',
        ]);
    }
}

PHP Attributes

Seit Laravel 11 können Sie anstelle von Namenskonventionen PHP Attributes verwenden.
AttributeZweck
#[Boot]Markiert eine statische Methode, die einmal beim Klassen-Boot ausgeführt wird
#[Initialize]Markiert eine Instanzmethode, die bei jeder Instanziierung ausgeführt wird
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;
    }
}
Durch die Verwendung von PHP Attributes werden Ihre Methodennamen von der Einschränkung des Trait-Namens befreit. Sie können außerdem mehrere #[Boot]- oder #[Initialize]-Methoden innerhalb desselben Traits definieren.

Praktische Beispiele

Globalen Scope automatisch hinzufügen

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

Standard-Casts zusammenführen

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

Automatisches Archivieren beim Löschen

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

Beispiele aus dem Framework

Die eigenen Traits von Laravel veranschaulichen das Muster deutlich:
TraitMethodeWas sie tut
SoftDeletesbootSoftDeletes()Registriert den globalen SoftDeletingScope
HasUlidsbootHasUlids()Setzt die ULID beim creating-Event
HasUuidsbootHasUuids()Setzt die UUID beim creating-Event
Diese Implementierungen zu lesen ist ein guter Weg, das Muster tiefergehend zu verstehen.

Hinweise

Booted Models in Tests zurücksetzen

Da boot* nur einmal pro Klasse ausgeführt wird, müssen Tests, die das Modellverhalten ändern, gegebenenfalls den Boot-Cache zurücksetzen:
protected function tearDown(): void
{
    Model::clearBootedModels();
    parent::tearDown();
}

Ausführungsreihenfolge

Wenn ein Modell mehrere Traits verwendet, werden bootXxx() und initializeXxx() in der PHP-Trait-Auflösungsreihenfolge (Deklarationsreihenfolge) aufgerufen. Achten Sie auf die Reihenfolge, wenn Traits voneinander abhängen.

Zusammenfassung

MusterWie definierenWann verwenden
Klassen-Bootstatic bootXxx() oder #[Boot]Event-Listener, globale Scopes
Instanz-InitialisierunginitializeXxx() oder #[Initialize]Standardwerte, dynamische Casts
Wenn Sie bootXxx() und initializeXxx() in einem Trait implementieren, können Sie mit einer einzigen use-Anweisung Verhalten in jedes Eloquent-Modell einfügen – das bevorzugte Muster für Paketautoren.
Zuletzt geändert am 13. Juli 2026