Passer au contenu principal

Introduction

Les accesseurs, mutateurs et casts d’attribut transforment les valeurs d’un modèle Eloquent lors de la lecture et de la définition sur l’instance.
  • Accesseur — transforme la valeur brute de la base avant de la passer à l’application
  • Mutateur — transforme la valeur fournie par l’application avant de l’enregistrer
  • Cast — permet de déclarer une conversion de type sans écrire de méthode

Définir un accesseur

Ajoutez une méthode protected sur le modèle. Nom en camelCase, retour de type Illuminate\Database\Eloquent\Casts\Attribute.
<?php

namespace App\Models;

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

class User extends Model
{
    /**
     * Récupère le prénom de l'utilisateur.
     */
    protected function firstName(): Attribute
    {
        return Attribute::make(
            get: fn (string $value) => ucfirst($value),
        );
    }
}
La closure get reçoit la valeur brute. Accédez au champ via first_name.
$user = User::find(1);

$firstName = $user->first_name; // Après application de ucfirst()
Pour inclure la valeur calculée dans le JSON / le tableau, ajoutez-la à $appends (en snake_case).

Objet valeur à partir de plusieurs attributs

get peut recevoir $attributes (tous les attributs du modèle) en 2ᵉ argument, pour combiner des colonnes en un objet valeur.
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'],
        ),
    );
}

Mise en cache des accesseurs

Les accesseurs retournant un objet valeur mémorisent automatiquement l’instance. Pour mettre en cache les types primitifs, appelez shouldCache().
protected function hash(): Attribute
{
    return Attribute::make(
        get: fn (string $value) => bcrypt(gzuncompress($value)),
    )->shouldCache();
}
Pour désactiver la mise en cache des objets, utilisez 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();
}

Définir un mutateur

Le mutateur se définit via l’argument set de Attribute::make(). Il peut cohabiter avec l’accesseur.
protected function firstName(): Attribute
{
    return Attribute::make(
        get: fn (string $value) => ucfirst($value),
        set: fn (string $value) => strtolower($value),
    );
}
À l’affectation, la closure set est appelée.
$user = User::find(1);
$user->first_name = 'SALLY'; // Enregistré sous 'sally'

Écrire dans plusieurs attributs

Si set retourne un tableau, plusieurs colonnes sont mises à jour.
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,
        ],
    );
}

Casts d’attribut

Les casts offrent une déclaration concise des conversions de type sans écrire d’accesseur/mutateur. La méthode casts() retourne un tableau.
<?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',
        ];
    }
}

Casts intégrés

CastDescription
integer / intEntier
float / double / realNombre à virgule
decimal:<digits>Décimal avec précision
stringChaîne
boolean / boolBooléen (incluant 0/1)
arrayJSON ⇔ tableau
objectJSON ⇔ objet
collectionJSON → Collection
dateDate (Carbon)
datetimeDateTime (Carbon)
immutable_dateDate immuable
immutable_datetimeDateTime immuable
timestampTimestamp UNIX
hashedHaché à l’écriture
encryptedChiffré à l’écriture
Les attributs null ne sont pas castés. Ne définissez pas non plus de cast portant le même nom qu’une relation, ni sur la clé primaire.

Cast Stringable

AsStringable traite l’attribut comme un Illuminate\Support\Stringable.
use Illuminate\Database\Eloquent\Casts\AsStringable;

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

Casts tableau et JSON

Les colonnes JSON/TEXT peuvent être manipulées comme des tableaux PHP.
protected function casts(): array
{
    return [
        'options' => 'array',
    ];
}
$user = User::find(1);

// Récupération en tableau PHP
$options = $user->options;

// Sérialisation JSON automatique à l'enregistrement
$user->options = array_merge($options, ['theme' => 'dark']);
$user->save();
L’opérateur -> met à jour une clé JSON précise.
$user->update(['options->theme' => 'dark']);

Casts AsArrayObject / AsCollection

Le cast standard array ne permet pas de modifier directement un offset. AsArrayObject ou AsCollection contournent ce problème.
use Illuminate\Database\Eloquent\Casts\AsArrayObject;
use Illuminate\Database\Eloquent\Casts\AsCollection;

protected function casts(): array
{
    return [
        'options' => AsArrayObject::class,   // Comme ArrayObject
        'tags'    => AsCollection::class,    // Comme Collection
    ];
}
Pour utiliser une classe de collection personnalisée, précisez using().
use App\Collections\TagCollection;
use Illuminate\Database\Eloquent\Casts\AsCollection;

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

Casts de date/heure

created_at / updated_at sont castés en Carbon par défaut. Faites de même pour vos colonnes.
protected function casts(): array
{
    return [
        'published_at' => 'datetime',
        'expires_at'   => 'immutable_datetime',
    ];
}
Un format spécifié détermine la sérialisation JSON.
protected function casts(): array
{
    return [
        'published_at' => 'datetime:Y-m-d',
    ];
}
Pour changer globalement le format de sérialisation, surchargez serializeDate() (n’affecte pas la persistance en base).
use DateTimeInterface;

protected function serializeDate(DateTimeInterface $date): string
{
    return $date->format('Y-m-d');
}
immutable_datetime renvoie un CarbonImmutable au lieu de Carbon, ce qui évite les effets de bord lors des manipulations de dates.

Casts Enum

Les Backed Enums de PHP 8.1+ peuvent servir de cast.
<?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,
    ];
}
La base stocke la valeur backing (string ou int) ; la lecture retourne l’instance Enum.
$server = Server::find(1);

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

Tableau d’Enums

Pour stocker plusieurs valeurs Enum dans une seule colonne, utilisez AsEnumCollection.
use App\Enums\ServerStatus;
use Illuminate\Database\Eloquent\Casts\AsEnumCollection;

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

Casts au niveau requête

Appliquez un cast dynamiquement à l’exécution de la requête avec 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();

Casts personnalisés

Vous pouvez créer vos propres casts en implémentant CastsAttributes et en définissant get / set.
php artisan make:cast AsJson
Pour l’implémentation détaillée (Value Object, casts entrants, Castables…), consultez la page avancée.

Casts personnalisés avancés

Implémentation de CastsAttributes, Value Object, Castables, etc.

Pages associées

Eloquent API Resources

Convertir des modèles en réponses JSON cohérentes.
Dernière modification le 13 juillet 2026