全13種類!Laravelのキャスト(型変換)実例

こんにちは。フリーランス・コンサルタント&エンジニアの 九保すこひ です。

さてさて、Laravelで開発をしているとき、とても重宝する機能の一つに、「データのキャスト(型変換)」があります。

キャストというのは、例えば文字列で登録したデータを数字に変換する機能で、通常のPHPだと、

$text = (string) 123;

とすることで型変換できるわけですけど、なんとLaravelの場合はモデルの$castsに指定するだけで、

  • 保存する時
  • 取得する時

の両方で、自動的に型変換をしてくれてとても便利です。(そして、変数の型だけじゃなく配列やコレクションに変換もしれくれます。)

例えばこんなカンジです。

class Item extends Model
{
    protected $casts = [
        'activated' => 'boolean'
    ];
}

とうことで、今回はこの「キャスト」の実例をまとめてみました。

開発環境: Laravel 5.4、Laravel 7.x

【追記:2020.03.10】この記事は、公開当時Laravel 5.4向けに作成されていたものに加筆修正したものです。

Integer

数字へ変換するキャストです。

もしデータが文字列でもこのキャストを使うことで型を数字にすることができます。

protected $casts = [
    'field_name' => 'integer'
];

例えば、”12345″という文字列がキャストされると、数字の「12345」に変換されます。

var_dump($item->field_name);   // int(12345)

ちなみに、もし文字列で “1234.555”などのように小数点がついている場合は、小数点以下が削除されて「1234」となります。(四捨五入ではない)

また、「150個」「150円50銭」という文字列の場合は、最初に出てくる数字「150」が取得できます。

float(real, double)

データを小数点つきの数字に変換するキャスト。(realdoubleは同じものなので、floatで統一します)

protected $casts = [
    'field_name' => 'float' // もしくは、real か double
];

もし”123.456″という文字列がfloatキャストされると、「123.456」という小数点付きの数字になります。

var_dump($item->field_name);   // float(123.456)

integerキャストと同じく、”123.456回”や”123.456円50銭”の場合は、「123.456」という小数点付きの数字になります。

String

データを文字列化するキャストです。

protected $casts = [
    'field_name' => 'string'
];

例えば、「12345」という数字がキャストされると”12345″という文字列に変換されます。

var_dump($item->field_name);   // string(5) "12345"

ちなみに、float型の場合も同様に文字列に変換されます。

var_dump($item->field_name);   // string(7) "12345.6"

boolean

データをtrueもしくは、falseに変換するキャストです。

protected $casts = [
    'field_name' => 'boolean'
];

例えば、データが「1」という数字の場合は以下のようにtrueになり、「0」の場合はfalseになります。

var_dump($item->field_name);   // bool(true) もしくは bool(false)

ちなみに、trueになるパターン、falseになるパターンは以下のとおりです。

  • true ・・・ 1, 2, -1
  • false ・・・ 0, 文字列の空白

※マイナス1は直感的にfalseになりそうですけど、実際にはtrueになってしまうので注意が必要ですね。

object

PHPの「stdClass」に変換されるキャストです。

protected $casts = [
    'colors' => 'object'
];

例えば、以下のように連想配列を保存すると、json化されてデータベースに格納されます。(連想配列、多次元配列でもOK)

\App\Item::create([
    'colors' => [
        'red' => '赤', 
        'blue' => '青', 
        'yellow' => '黄色'
    ]
]);

↓↓↓DB内

{"red":"\u8d64","blue":"\u9752","yellow":"\u9ec4\u8272"}

そして、データ取得した場合は、以下のようにstdClassとして利用できます。

var_dump($item->colors->red);   // string(3) "赤"
var_dump($item->colors->blue);   // string(3) "青"
var_dump($item->colors->yellow);   // string(6) "黄色"

ちなみに、stdClassはforeach()ループで使うこともできます。

foreach ($item->colors as $key => $value) {

    echo $key .': '. $value ."\n";

}

/*** 出力

red: 赤
blue: 青
yellow: 黄色

***/

array

データを配列化してくれるキャストです。

protected $casts = [
    'colors' => 'array'
];

配列を保存すると、データがjson化されます。(連想配列、多次元配列でもOK)

\App\Item::create([
    'colors' => [
        '赤',
        '青',
        '黄色'
    ]
]);

↓↓↓DB内

["\u8d64","\u9752","\u9ec4\u8272"]

取得したところ。

var_dump($item->colors);

/*** 出力

    array(3) {
      [0]=>
      string(3) ""
      [1]=>
      string(3) ""
      [2]=>
      string(6) "黄色"
    }
 
***/

collection

Laravelの「コレクション」に変換してくれるキャストです。
これも「array」や「object」などと同じく保存するとjson化されます。

protected $casts = [
    'colors' => 'collection'
];

データ取得するとこうなります。

var_dump($item->colors);

/*** 出力

    object(Illuminate\Support\Collection)#699 (1) {
        ["items":protected]=>
        array(3) {
            ["red"]=>
            string(3) ""
            ["blue"]=>
            string(3) ""
            ["yellow"]=>
            string(6) "黄色"
        }
    }

***/

date, datetime

Carbonインスタンスに変換してくれるキャストです。

protected $casts = [
    'start_date' => 'date',
    'start_datetime' => 'datetime'
];
var_dump($item->start_date);

/*** 出力

object(Illuminate\Support\Carbon)#700 (3) {
  ["date"]=>
  string(26) "2018-05-15 00:00:00.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(10) "Asia/Tokyo"
}

***/

dateとdatetimeの違いは、dateの場合、時間/分/秒が全てゼロになることです。これは、データが「2018-05-15 01:15:30」という風に時分秒が指定されていても同じです。

echo $music->start_date->hour; // 0
echo $music->start_date->minute; // 0
echo $music->start_date->second; // 0

ちなみに、データが空白の場合は「Data missing」というエラーが発生します。

なお、以下のように日付のフォーマットを指定することができます。

protected $casts = [
    'start_date' => 'datetime:Y年m月d日'
];

詳しくは、過去記事「Laravel5.6の気になる3つの新機能」の「2.モデル内の日付・自動変換」を参照してください。

timestamp

データをUNIX時間に変換してくれるキャストです。つまりint型になります。

protected $casts = [
    'created_at' => 'timestamp'
];
var_dump($item->created_at); // int(1526314530)

カスタムキャスト機能

Laravel 7.xからは、独自キャストを作ることができる「カスタムキャスト機能」が追加になっています。詳しくは以下のURLをご覧ください。

Laravel 7.xの新しいキャスト(データ変換)機能!実例

クエリー用の時間キャスト

【注意】この機能は、Laravel 7.x以降で有効です。

例えば、userspostsが1:多(hasMany)の関係にあるとして、「認証されたpostデータの最新の日付を取得する」場合を考えてみましょう。

コードとしては以下のようになります。

$users = \App\User::select([
    'users.id',
    'verified_at' => \App\Post::selectRaw('MAX(verified_at)')
        ->whereColumn('user_id', 'users.id')
])->get();

ただ、この場合だとverified_atは文字列なので、日付オブジェクトとして使う場合はnew Carbon()で変換する必要があり、めんどうです。

そんな場合に重宝するのが、withCasts()です。
以下のように使うことで、元々は文字列だったverified_atを日付にキャストすることができます。

$users = \App\User::select([
    'users.id',
    'verified_at' => \App\Post::selectRaw('MAX(verified_at)')
        ->whereColumn('user_id', 'users.id')
])->withCasts([
    'verified_at' => 'date' // 日付に変換
])->get();
開発のご依頼お待ちしております
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします! by 九保すこひ

おわりに

ということで、今回はキャストをまとめてみました。
みなさんのお役に立てたら嬉しいです!

ではでは〜。

このエントリーをはてなブックマークに追加       follow us in feedly