Zum Hauptinhalt springen

Einführung

Accessors, Mutators und Attribute Casts transformieren Werte eines Eloquent-Modells beim Lesen und Schreiben auf einer Modellinstanz.
  • Accessor – veredelt den Rohwert aus der Datenbank für die Verwendung in der Anwendung
  • Mutator – transformiert den in der Anwendung gesetzten Wert, bevor er in die Datenbank geht
  • Cast – definiert deklarativ Typkonvertierungen für Attribute, ohne dass zusätzliche Methoden nötig wären

Accessor definieren

Für einen Accessor fügen Sie eine protected Methode zum Modell hinzu. Der Methodenname folgt CamelCase-Konvention, der Rückgabetyp ist Illuminate\Database\Eloquent\Casts\Attribute.
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Liefert den Vornamen des Nutzers.
     */
    protected function firstName(): Attribute
    {
        return Attribute::make(
            get: fn (string $value) => ucfirst($value),
        );
    }
}
Die get-Closure erhält den Rohwert aus der Datenbank. Auf der Modellinstanz greifen Sie über die Property first_name zu.
$user = User::find(1);

$firstName = $user->first_name; // Wert nach ucfirst()
Wenn Sie den vom Accessor berechneten Wert in JSON- oder Array-Ausgaben aufnehmen möchten, tragen Sie ihn in der $appends-Property des Modells als Snake-Case ein.

Wertobjekt aus mehreren Attributen erzeugen

Die get-Closure kann als zweites Argument $attributes erhalten (alle Attribute des Modells). Damit können Sie mehrere Spalten zu einem Wertobjekt kombinieren.
use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;

protected function address(): Attribute
{
    return Attribute::make(
        get: fn (mixed $value, array $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
    );
}

Caching von Accessors

Accessors, die Wertobjekte zurückgeben, cachet Eloquent automatisch, sodass dieselbe Instanz zurückgegeben wird. Möchten Sie auch primitive Typen wie Strings oder Zahlen cachen, rufen Sie shouldCache() auf.
protected function hash(): Attribute
{
    return Attribute::make(
        get: fn (string $value) => bcrypt(gzuncompress($value)),
    )->shouldCache();
}
Um das Objekt-Caching auszuschalten, verwenden Sie withoutObjectCaching().
protected function address(): Attribute
{
    return Attribute::make(
        get: fn (mixed $value, array $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
    )->withoutObjectCaching();
}

Mutator definieren

Ein Mutator wird über das Argument set von Attribute::make() definiert und lässt sich zusammen mit dem Accessor in derselben Methode ablegen.
protected function firstName(): Attribute
{
    return Attribute::make(
        get: fn (string $value) => ucfirst($value),
        set: fn (string $value) => strtolower($value),
    );
}
Beim Setzen des Werts wird die set-Closure aufgerufen.
$user = User::find(1);
$user->first_name = 'SALLY'; // strtolower() wird angewendet, 'sally' wird gespeichert

In mehrere Attribute schreiben

Gibt die set-Closure ein Array zurück, können mehrere Spalten gleichzeitig aktualisiert werden.
use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;

protected function address(): Attribute
{
    return Attribute::make(
        get: fn (mixed $value, array $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
        set: fn (Address $value) => [
            'address_line_one' => $value->lineOne,
            'address_line_two' => $value->lineTwo,
        ],
    );
}

Attribute Casts

Casts sind eine bequeme Möglichkeit, Typkonvertierungen deklarativ zu definieren, ohne dafür Accessors und Mutators zu schreiben. Über die Methode casts() Ihres Modells geben Sie ein Array zurück.
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected function casts(): array
    {
        return [
            'is_admin'   => 'boolean',
            'score'      => 'float',
            'settings'   => 'array',
            'created_at' => 'datetime',
        ];
    }
}

Eingebaute Casts im Überblick

CastBeschreibung
integer / intGanzzahl
float / double / realGleitkommazahl
decimal:<Nachkommastellen>Dezimalzahl mit fester Nachkommastellenzahl
stringZeichenkette
boolean / boolBoolescher Wert (auch aus 0/1)
arrayWandelt JSON in ein Array um und zurück
objectWandelt JSON in ein Objekt um und zurück
collectionWandelt JSON in eine Collection
dateDatum (Carbon)
datetimeDatum und Uhrzeit (Carbon)
immutable_dateUnveränderliches Datum
immutable_datetimeUnveränderliches Datum und Uhrzeit
timestampUNIX-Timestamp
hashedHasht den Wert beim Speichern
encryptedVerschlüsselt den Wert beim Speichern
Attribute mit null-Wert werden nicht gecastet. Legen Sie außerdem keine Casts an, deren Name dem einer Relation entspricht, und wandeln Sie den Primärschlüssel nicht per Cast um.

Stringable-Cast

Mit AsStringable verwenden Sie ein Attribut als Illuminate\Support\Stringable-Objekt.
use Illuminate\Database\Eloquent\Casts\AsStringable;

protected function casts(): array
{
    return [
        'bio' => AsStringable::class,
    ];
}

Array-/JSON-Casts

JSON- oder TEXT-Spalten können transparent als PHP-Array behandelt werden.
protected function casts(): array
{
    return [
        'options' => 'array',
    ];
}
$user = User::find(1);

// Automatisch als PHP-Array geladen
$options = $user->options;

// Beim Speichern automatisch als JSON serialisiert
$user->options = array_merge($options, ['theme' => 'dark']);
$user->save();
Mit dem Operator -> können Sie auch einzelne Schlüssel innerhalb des JSON aktualisieren.
$user->update(['options->theme' => 'dark']);

Casts AsArrayObject / AsCollection

Der Standard-array-Cast führt zu einem Fehler, wenn Sie einzelne Array-Offsets direkt ändern möchten. Mit AsArrayObject und AsCollection umgehen Sie dieses Problem.
use Illuminate\Database\Eloquent\Casts\AsArrayObject;
use Illuminate\Database\Eloquent\Casts\AsCollection;

protected function casts(): array
{
    return [
        'options' => AsArrayObject::class,   // wie ein ArrayObject behandeln
        'tags'    => AsCollection::class,    // wie eine Collection behandeln
    ];
}
Für eine eigene Collection-Klasse verwenden Sie using().
use App\Collections\TagCollection;
use Illuminate\Database\Eloquent\Casts\AsCollection;

protected function casts(): array
{
    return [
        'tags' => AsCollection::using(TagCollection::class),
    ];
}

Datums-Casts

created_at und updated_at werden standardmäßig zu Carbon gecastet. Weitere Datumsfelder können auf dieselbe Weise definiert werden.
protected function casts(): array
{
    return [
        'published_at' => 'datetime',
        'expires_at'   => 'immutable_datetime',
    ];
}
Wenn Sie ein Format angeben, wird dieses bei der JSON-Serialisierung verwendet.
protected function casts(): array
{
    return [
        'published_at' => 'datetime:Y-m-d',
    ];
}
Möchten Sie das Standard-Serialisierungsformat für alle Datumsfelder ändern, überschreiben Sie serializeDate() (das Speicherformat in der Datenbank bleibt davon unberührt).
use DateTimeInterface;

protected function serializeDate(DateTimeInterface $date): string
{
    return $date->format('Y-m-d');
}
Mit immutable_datetime erhalten Sie statt eines Carbon-Objekts eine CarbonImmutable-Instanz. Da sich diese Instanz beim Manipulieren nicht ändert, lässt sich damit besonders nebeneffektfreier Code schreiben.

Enum-Casts

Ab PHP 8.1 lassen sich Backed Enums als Cast angeben.
<?php

namespace App\Enums;

enum ServerStatus: string
{
    case Provisioned = 'provisioned';
    case Ready       = 'ready';
    case Archived    = 'archived';
}
use App\Enums\ServerStatus;

protected function casts(): array
{
    return [
        'status' => ServerStatus::class,
    ];
}
In der Datenbank wird der Backing-Wert (string oder int) des Enums gespeichert; beim Lesen wird eine Enum-Instanz zurückgegeben.
$server = Server::find(1);

if ($server->status === ServerStatus::Provisioned) {
    $server->status = ServerStatus::Ready;
    $server->save();
}

Array-Cast für Enums

Wenn Sie mehrere Enum-Werte als Array in einer Spalte speichern möchten, verwenden Sie AsEnumCollection.
use App\Enums\ServerStatus;
use Illuminate\Database\Eloquent\Casts\AsEnumCollection;

protected function casts(): array
{
    return [
        'statuses' => AsEnumCollection::of(ServerStatus::class),
    ];
}

Casts zur Query-Laufzeit

Um Casts dynamisch beim Ausführen einer Query anzuwenden, verwenden Sie withCasts().
use App\Models\Post;
use App\Models\User;

$users = User::select([
    'users.*',
    'last_posted_at' => Post::selectRaw('MAX(created_at)')
        ->whereColumn('user_id', 'users.id'),
])->withCasts([
    'last_posted_at' => 'datetime',
])->get();

Benutzerdefinierte Casts

Sie können eigene Cast-Klassen erstellen. Implementieren Sie das Interface CastsAttributes und definieren Sie die Methoden get und set.
php artisan make:cast AsJson
Details zur Umsetzung (Value-Object-Muster, Inbound Casts, Castables usw.) finden Sie auf der weiterführenden Seite.

Benutzerdefinierte Casts im Detail

Erläutert die Implementierung des CastsAttributes-Interfaces sowie fortgeschrittene Muster wie Value Objects und Castables.

Verwandte Seiten

Eloquent-API-Ressourcen

Erfahren Sie, wie Sie Modelle mit Resource-Klassen in konsistente JSON-API-Antworten umwandeln.
Zuletzt geändert am 13. Juli 2026