Ü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 aufgerufen | Einmal, wenn die Modellklasse erstmals bootet | Bei jeder Instanzerstellung |
| Methodentyp | static | Instanzmethode |
| Typische Verwendung | Event-Listener registrieren, globale Scopes hinzufügen | Standard-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.
| Attribute | Zweck |
|---|
#[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:
| Trait | Methode | Was sie tut |
|---|
SoftDeletes | bootSoftDeletes() | Registriert den globalen SoftDeletingScope |
HasUlids | bootHasUlids() | Setzt die ULID beim creating-Event |
HasUuids | bootHasUuids() | 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
| Muster | Wie definieren | Wann verwenden |
|---|
| Klassen-Boot | static bootXxx() oder #[Boot] | Event-Listener, globale Scopes |
| Instanz-Initialisierung | initializeXxx() 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