メインコンテンツへスキップ

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モデルの属性値をモデルインスタンスで取得・設定するときに変換する仕組みです。
  • アクセサ — DBから取得した生の値を加工してアプリケーションに渡す
  • ミューテタ — アプリケーションからセットされた値を加工してDBに保存する
  • キャスト — 追加メソッドなしで属性の型変換を宣言的に定義する

アクセサの定義

アクセサを定義するには、モデルに protected メソッドを追加します。メソッド名はキャメルケース、戻り値型は Illuminate\Database\Eloquent\Casts\Attribute にします。
<?php

namespace App\Models;

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

class User extends Model
{
    /**
     * ユーザーのファーストネームを取得します。
     */
    protected function firstName(): Attribute
    {
        return Attribute::make(
            get: fn (string $value) => ucfirst($value),
        );
    }
}
get クロージャにDBの生の値が渡されます。モデルインスタンスから first_name プロパティとしてアクセスできます。
$user = User::find(1);

$firstName = $user->first_name; // ucfirst() が適用された値
アクセサで計算した値をJSON/配列に含めたい場合は、モデルの $appends プロパティにスネークケースで追加してください。

複数の属性から値オブジェクトを生成する

get クロージャは第2引数として $attributes(モデルのすべての属性)を受け取れます。複数カラムを組み合わせて1つの値オブジェクトを返すことができます。
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'],
        ),
    );
}

アクセサのキャッシュ

値オブジェクトを返すアクセサは、Eloquentが同じインスタンスを返すよう自動でキャッシュします。文字列や数値など基本型でもキャッシュしたい場合は shouldCache() を呼び出します。
protected function hash(): Attribute
{
    return Attribute::make(
        get: fn (string $value) => bcrypt(gzuncompress($value)),
    )->shouldCache();
}
オブジェクトのキャッシュを無効にしたい場合は 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();
}

ミューテタの定義

ミューテタは Attribute::make()set 引数として定義します。アクセサと同じメソッドにまとめられます。
protected function firstName(): Attribute
{
    return Attribute::make(
        get: fn (string $value) => ucfirst($value),
        set: fn (string $value) => strtolower($value),
    );
}
モデルに値をセットすると set クロージャが呼ばれます。
$user = User::find(1);
$user->first_name = 'SALLY'; // strtolower() が適用されて 'sally' が保存される

複数の属性に書き込む

set クロージャから配列を返すと、複数のカラムをまとめて更新できます。
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() メソッドで配列を返します。
<?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',
        ];
    }
}

組み込みキャスト一覧

キャスト説明
integer / int整数
float / double / real浮動小数点数
decimal:<桁数>指定桁数の小数
string文字列
boolean / bool真偽値(0/1 を含む)
arrayJSONを配列に相互変換
objectJSONをオブジェクトに相互変換
collectionJSONをコレクションに変換
date日付(Carbon)
datetime日時(Carbon)
immutable_dateイミュータブルな日付
immutable_datetimeイミュータブルな日時
timestampUNIXタイムスタンプ
hashed保存時にハッシュ化
encrypted保存時に暗号化
null の属性はキャストされません。また、リレーション名と同じ名前のキャストや、主キーへのキャストは定義しないでください。

Stringable キャスト

AsStringable を使うと、属性を Illuminate\Support\Stringable オブジェクトとして扱えます。
use Illuminate\Database\Eloquent\Casts\AsStringable;

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

配列・JSON キャスト

JSON/TEXT カラムを PHP 配列として透過的に扱えます。
protected function casts(): array
{
    return [
        'options' => 'array',
    ];
}
$user = User::find(1);

// 自動的にPHP配列として取得
$options = $user->options;

// 変更して保存すると自動的にJSONシリアライズされる
$user->options = array_merge($options, ['theme' => 'dark']);
$user->save();
-> 演算子で JSON の特定キーだけを更新することもできます。
$user->update(['options->theme' => 'dark']);

AsArrayObject / AsCollection キャスト

標準の array キャストは、配列の特定オフセットを直接変更しようとするとエラーになります。AsArrayObjectAsCollection を使うとこの問題を回避できます。
use Illuminate\Database\Eloquent\Casts\AsArrayObject;
use Illuminate\Database\Eloquent\Casts\AsCollection;

protected function casts(): array
{
    return [
        'options' => AsArrayObject::class,   // ArrayObjectとして扱う
        'tags'    => AsCollection::class,    // Collectionとして扱う
    ];
}
カスタムコレクションクラスを使いたい場合は using() を指定します。
use App\Collections\TagCollection;
use Illuminate\Database\Eloquent\Casts\AsCollection;

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

日時キャスト

created_at / updated_at はデフォルトで Carbon にキャストされます。追加の日時カラムも同様に定義できます。
protected function casts(): array
{
    return [
        'published_at' => 'datetime',
        'expires_at'   => 'immutable_datetime',
    ];
}
フォーマットを指定すると、JSON シリアライズ時にそのフォーマットが使われます。
protected function casts(): array
{
    return [
        'published_at' => 'datetime:Y-m-d',
    ];
}
すべての日付のデフォルトシリアライズフォーマットを変えたい場合は serializeDate() をオーバーライドします(DB保存フォーマットには影響しません)。
use DateTimeInterface;

protected function serializeDate(DateTimeInterface $date): string
{
    return $date->format('Y-m-d');
}
immutable_datetime を使うと Carbon の代わりに CarbonImmutable が返ります。元のインスタンスを変更せずに日時操作できるため、副作用のないコードを書きやすくなります。

Enum キャスト

PHP 8.1 以降の Backed Enum をキャストとして指定できます。
<?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,
    ];
}
DBには Enum のバッキング値(string または int)が保存され、取得時には Enum インスタンスに変換されます。
$server = Server::find(1);

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

Enum の配列キャスト

複数の Enum 値を1カラムに配列として保存したい場合は AsEnumCollection を使います。
use App\Enums\ServerStatus;
use Illuminate\Database\Eloquent\Casts\AsEnumCollection;

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

クエリ時のキャスト

クエリ実行時に動的にキャストを適用するには 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();

カスタムキャスト

独自のキャストクラスを作成することも可能です。CastsAttributes インターフェースを実装し、getset メソッドを定義します。
php artisan make:cast AsJson
詳細な実装方法(Value Object パターン、インバウンドキャスト、Castables など)は以下の上級ページを参照してください。

カスタムキャスト詳解

CastsAttributes インターフェースの実装方法や、Value Object パターン・Castables など上級のカスタムキャストを解説します。

関連ページ

Eloquent APIリソース

モデルを一貫したJSON APIレスポンスに変換するリソースクラスの使い方を確認します。
Last modified on April 12, 2026