🖼️

最近のLarvelで書き方が変わったもの

2025/01/14に公開

PHPとともに進化

Laravelは後方互換がしっかりしているので気づきにくいが、
構文が新しくなっているものも結構ある
(Laravel8とそれ以前ではだいぶ違う)

忘れがちなのでまとめていこう

ヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪

------------------- ↓ 本題はここから ↓-------------------

Route

URLを確定させ、Controllerと接続するときに設定するRoute
もともとは Controller@index みたいに文字列で指定していたが、
Laravel8以降で配列指定になっている

use Illuminate\Support\Facades\Route;
Route::get('/user', 'UserController@index');
Laravel8以降
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;
Route::get('/user', [UserController::class, 'index']);

Routeから辿れるようになって使いやすい
(^^♪

Accessors & Mutators

モデルのプロパティはデータベースのカラムを指しているが、
データを取り出す、入れ込む際に状態を変えたい場合がある
(日付のフォーマット変えたいとか)
その時に、使うのがアクセサ、ミューテタ。

以前は get〇〇Attribute、set〇〇Attributeと記述する方式だったが、
今はもうちょっとスマートになっている
(使うかどうかはまた別の話)

public function getFullNameAttribute() {
  return "{$this->first_name} {$this->last_name}";
}
public function setFirstNameAttribute($value) {
  $this->attributes['first_name'] = strtolower($value);
}
Laravel9以降
protected function firstName(): Attribute {
  return Attribute::make(
    get: fn ($value) => ucfirst($value),
    set: fn ($value) => strtolower($value),
  );
}

PHP8.4のプロパティフックもこれに近いやも
(・ω・)

Factory

こちらは記述自体が大きく変わっている
正直以前のFactoryはなんだかよくわからない感じだった

use Faker\Generator as Faker;
use Illuminate\Support\Str;
 
$factory->define(App\User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
        'remember_token' => Str::random(10),
    ];
});
Laravel8以降
namespace Database\Factories;
 
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
 
class UserFactory extends Factory
{
    public function definition()
    {
        return [
            'name' => fake()->name(),
            'email' => fake()->unique()->safeEmail(),
            'email_verified_at' => now(),
            'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
            'remember_token' => Str::random(10),
        ];
    }
}

旧式のFactoryが残っていたら作り直すのもありかな

Request

safeの戻り値ValidatedInput

Requestメソッドには型を調整してくれる機能が備わっている
参考書とかは以下のように取るようになってると思う

$count = $request->count;
$isRequire = $request->input('isRequire');

実際は型を変えて取得する

$count = $request->integer('count');
$isRequire = $request->boolean('isRequire');

これがsafe実行後でも使えるようになった

Laravel10.48.19以降
/** @var ValidatedInput $validated */
$validated = $request->safe();
$count = $validated->integer('count');
$isRequire = $validated->boolean('isRequire');

safeは使いやすいのでこれは地味にありがたい
(^_-)-☆

Closure Rules Message

Requestにバリデーションルールを記載するのは同じだが、
ここにクロージャを直接書くことができるが、
失敗時のメッセージを登録できるようになった

Laravel10以降
public function rules()
{
    'name' => [
        function ($attribute, $value, $fail) {
            $fail('validation.translation.key')->translate();
        },
    ],
}

同様にValidatorでも。

withValidator

細かい内容ではあるが、
まぁまぁ使うwithValidator メソッドから afer メソッドを使う方式に変わっている
(互換性のためwithValidatorは残っている)

https://laravel.com/docs/10.x/upgrade#form-request-after-method

以下のようなRuleクラスがあったとする

AfterRule
<?php

class AfterRule
{
    public function __invoke($validator): void
    {
        if (/* ... */) {
            $validator->errors()->add(/* ... */);
        }

        if (/* ... */) {
            $validator->errors()->add(/* ... */);
        }

        if (/* ... */) {
            $validator->errors()->add(/* ... */);
        }
    }
}

現状、withValidator で以下のように使用する

<?php

class UserRequest
{
    public function withValidator($validator): void
    {
        $service = app(MyService::class);
        $validator->after([
            new AfterRule($this->value, $service),
        ]);
    }
}

これをRequest側に after クラスを作成して、
配列で列挙する形になっている。

Laravel10以降
<?php

class UserRequest
{
   protected function after(MyService $service): array
    {
        return [
            new AfterRule($this->value, $service),
            // ...
        ];
    }
}

Discussion