Laravel 8.x の新機能・変更点のまとめ

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

さてさて、2020年の3月に7.xがリリースされたLaravelですが、約半年の期間を経て、この9月8日に「バージョン8.x」が公開されることになりました。🎉✨

そして、Laravelが大好きな開発者として、時期バージョンが気になってしょうがないので、ちょっとフライングしてリリースノートに書かれている内容をシンプルにまとめてみることにしました。(8.xのページがすでに存在していました)

ぜひ皆さんの今後の参考になれば嬉しいです。

※なお、8.xのリリース前に書いた記事ですので内容が変更になることも考えられます。そのあたりはご了承ください。また、まだ実際に動かしていない部分もありますので、今後変更する可能性もあります。

では、ひとつずつ見ていきましょう❗

【追記:2020.09.08】オートインクリメントについての新機能を追加しました
【追記:2020.09.24】ルート設定の変更点を追加しました

「Laravel開発者のみなさん、
お疲れ様でございます!」

Laravel 8.xで必要になる環境

新機能の紹介に行く前に、まず実行環境を見ていきたいと思います。

  • PHP >= 7.3 👈
  • BCMath PHP Extension
  • Ctype PHP Extension
  • Fileinfo PHP extension
  • JSON PHP Extension
  • Mbstring PHP Extension
  • OpenSSL PHP Extension
  • PDO PHP Extension
  • Tokenizer PHP Extension
  • XML PHP Extension

PHPの拡張機能としては、前バージョンと同じですが、ついにPHPの最低バージョンに7.3が必要になりました。

私の環境にもこの間PHP 7.4を導入したのですが、着々とバージョンが進んでいき、こうなるとLaravel 5.0 ~ 5.6あたりのプログラムとの付き合い方も考えないといけないなと考え出しています。

サポート期間は?

いわゆる「LTS」(長くサポートしてくれるバージョン)ではありません。

サポートは、以下の予定です。

  • バグ修正のサポート: 2021年3月8日まで
  • セキュリティのサポート: 2021年9月8日まで

そのため、もしより長いサポートの方がいい場合は、一番新しいLTSバージョンの6.xををおすすめします。

6.xのサポートは以下になります。

  • バグ修正のサポート: 2021年9月3日まで
  • セキュリティのサポート: 2022年9月3日まで

Laravel Jetstream

Laravelは、バージョン6.xからログイン機能が別パッケージのlaravel/uiをインストールする形になっていましたが、これが新パッケージLaravel Jetstreamと入れ替わりになるようです。

詳しい機能で言うと、次のとおりです。

  • ログイン
  • ユーザー登録
  • メール認証(本人確認、本登録メール)
  • 2段階認証
  • セッション管理
  • API(Laravel Sanctum)
  • チーム管理 👈 おっ❗

この中で私が気になったのは「チーム管理」です。

この機能は、「ユーザーの役割」が管理できるようになるため、これまではわざわざマイグレーションにroleのようなフィールドを追加してましたが、省略できそうです😊

さらに、このJetstreamのもう一つの特徴として、利用しているCSSフレームワークがbootstrapではなく、Tailwind CSS になっていることが挙げられます。(このあたりは、CSSフレームワーク業界の変遷を感じずにはいられません)

また、JSのシステムとしてlivewireかSPA(シングル・ページ・アプリケーション)向けのinertiaを選ぶことになるようです。

※ livewireの詳しい内容は過去記事をご覧ください。

【過去記事】Laravel + livewireで誕生日から年齢を自動計算するサンプル

ちなみに、私の好きなVue.jsとも連携できるようですが、このあたりは今後の記事でご紹介しようと考えています👍

モデルのディレクトリが変更になる

これまで、Laravelのモデルは初期状態ではapp直下に設置するようになっていましたが、要望が多かったようで8.xからはapp/Modelsが初期フォルダになるようです。

(確かにコントローラーやViewは専用フォルダがあるのに、モデルだけないというのは違和感はありましたよね)

ただし、app直下に慣れてしまった人のために、もしapp/Modelsを削除すれば、php artisan make:model ****を実行してもこれまでどおりapp直下にファイルを作ってくれるようです。

Factory の構造が変更になる

Factoryは、テストデータを作成する場面で使われる「データ生成器」ですが、この構造が以下のようなfunctionを使う形から、クラスベースになるようです。

// これまでの書き方

$factory->define(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),
    ];
});
// 新しい書き方: クラスを使う形へ移行

class UserFactory extends Factory
{
    protected $model = User::class;

    public function definition()
    {
        return [
            'name' => $this->faker->name,
            'email' => $this->faker->unique()->safeEmail,
            'email_verified_at' => now(),
            'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
            'remember_token' => Str::random(10),
        ];
    }
}

そして、使い方も次のようなコードから、

$user = factory(App\User::class)->make();

このように変更になります。

\App\Models\User::factory()->create();

マイグレーションをひとまとめにしてくれるMigration Squashing

開発するシステムが大きくなるにつれて、マイグレーションのファイルが大量になってしまうことがあると思いますが、この場合「Migration Squashing」がDBデータをひとまとめにして1つのファイルにしてくれるようです。

ちなみにファイルは、「database/schema」ディレクトリに作成され、コマンドは、「php artisan schema:dump」です。

また、作成されるファイルはSQLファイルとのことですので、この機能を使えば、それ以降は高速にマイグレーションが実行できる可能性がありますね。

Job Batching

Jobとは、タイマー実行する際に使う機能のことです。(詳しくは以下のページをご覧ください)

【参考記事】Laravelで定期的にタイマー実行する全16実例!

そして、Job Batchingはこのタイマーの一括処理を管理する機能のことです。

実際の例を見てみましょう。

$batch = Bus::batch([
    new ProcessPodcast(Podcast::find(1)), // 👈 1個目のJob
    new ProcessPodcast(Podcast::find(2)), // 👈 2個目のJob
    new ProcessPodcast(Podcast::find(3)), // 👈 3個目のJob
])->then(function (Batch $batch) {

    // 全ての処理がうまくいった場合...😄

})->catch(function (Batch $batch, Throwable $e) {

    // 途中でエラーが発生した場合...😫

})->finally(function (Batch $batch) {

    // どちらにしても通る

})->dispatch();

このように、徐々に実行されるJobの状況に応じて分岐する場所を変更することができるわけです。

なお、JavaScriptでの開発をされる方は「デジャブ感」あるんじゃないでしょうか。

そうです。「Promise.all()」とそっくりですね。

いくつか言語を体験しておくとこういうときに「あっ、これは!」となるので有利かもしれませんね👍

// Promise.all() の例

const promises = [
    new Promise((resolve, reject) => {
        resolve('1st');
    }),
    new Promise((resolve, reject) => {
        resolve('2nd');
    }),
    new Promise((resolve, reject) => {
        reject('3rd');
    })
];

Promise.all(promises)
    .then(value => {

        // 全ての処理がうまくいった場合...😄

    })
    .catch((error) => {

        // 途中でエラーが発生した場合...😫

    })
    .finally(() => {

        // どちらにしても通る

    });

Rate Limiting が改良された

Rate Limitingとは、簡単に言うと「何回までアクセスOK?」を決めることができる機能で、例えば無差別アクセスへの対処に使ったりできます。

そして、今回のアップグレードで、このRate Limitingがより汎用的になったようで、例えばダウンロード回数を制限するには以下のようにできるようになりました。

// ダウンロード回数を制限

$name = 'download';

RateLimiter::for($name, function(Request $request) {

    $user = $request->user();

    if($user->service === 'premium') { // プレミアム会員の場合

        Limit::none(); // 無制限

    } else { // 無料会員

        Limit::perMinute(3); // 1分間に3回まで

    }

});

そして、定義をしたらミドルウェアの引数として以下のように使えます。

Route::middleware(['throttle:download'])->group(function() {
    
    // ここに制限をかけるルート
    
});

メンテナンスモードが変更になった

前回まではメンテナンス・モードが実行されていても「許可IPアドレス」を登録しておけば通常通りサイトにアクセスできていましたが、これが廃止になったようです。

そして、その代わりに以下のようにトークンを設定し、

php artisan down --secret="1630542a-246b-4b66-afa1-dd72a4c43515"

次のようにURLに含めてアクセスすると、クッキーを発行してくれてトップページへリダイレクトしてくれます。

https://(あなたのサイト)/1630542a-246b-4b66-afa1-dd72a4c43515

Queueにcatch()が追加された

キューとは、大量の処理をするときにサーバーに負荷がかからないよう「後でちょっとずつ実行するね」機能のことで、そのキューを実行する際にcatch()が使えるようになりました。

dispatch(function () use ($post) {

    $post->publish();

})->catch(function (Throwable $e) {
    
    // 処理に失敗したとき

});

Dynamic Blade コンポーネント

例えば、ユーザーの情報を元にして実行するコンポーネントが違ってくるときがありますが、そんなときに使えるのが「Dynamic Blade コンポーネント」です。

以下のようにすることで、$component_nameの中身で呼び出すコンポーネントが自動で切り替わるようです。

<x-dynamic-component :component="$component_name" />

Event::listener()が改善された

イベントを手動で登録するには、EventServiceProviderboot()内に以下のように直接登録をすることができます。

Event::listen('event.name', function ($foo, $bar) {

    //

});

そして、今回のアップグレードで以下のようにすることで「どのイベントなのか」をチェックしてくれるようになりました。

Event::listen(function (ProductOrdered $event) {

    //

});

時間のテストがしやすくなった

システム開発をしていると、たまに「未来や過去の日付のときにうまくいく??」というテストをする必要が出てきます。

これまでは、日付パッケージCarbonを使って以下のようにすることで、「(実際には違うけれども)今は、指定の時間とする」ことができました。

$date = Carbon::create(2001, 5, 21, 12);
Carbon::setTestNow($date);

もちろんこの方法でもいいですが、今回のアップグレードでは以下のようにすることでより直感的に同じことができるようになりました。

public function testTimeCanBeManipulated()
{
    $this->travel(5)->milliseconds(); // 5ミリ秒後(として実行)
    $this->travel(5)->seconds(); // 5秒後(として実行)
    $this->travel(5)->minutes(); // 5分後(として実行)
    $this->travel(5)->hours(); // 5時間後(として実行)
    $this->travel(5)->days(); // 5日後(として実行)
    $this->travel(5)->weeks(); // 5週後(として実行)
    $this->travel(5)->years(); // 5年後(として実行)

    $this->travel(-5)->hours(); // 過去もOK

    $this->travelTo(now()->subHours(6)); // 今から6時間前

    $this->travelBack(); // 現在の時間に戻る
}

つまり、ドラえもんのタイムマシンのような感覚で使えるということですね👍

php artisan serveコマンドが自動で再起動するようになった

もし.envファイルに変更があった場合、自動でこれをキャッチして再起動してくれるようになりました。

ページ送りのリンクがTailwind CSSになった

ログイン機能のJetstreamでもBootstrapではなく、Tailwind CSSが使われるようになりましたが、同じくページリンクでもTailwind CSSに変更になったようです。

ただし、Boostrap 3 & 4 でも使えるそうです。

オートインクリメントが好きな番号から開始できるようになった

オートインクリメントは、1, 2, 3… というように順に採番してくれるDB機能のことで、Laravelでは主にテーブルのidに使われています。

そして、Laravel 8.xからはマイグレーションの中でこのオートインクリメントをどこから開始するかを決められるようになりました。

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
    $table->id()->startingValue(1200);

ルートの指定方法が変わった

元々ルートは次のように書いていました。

// Laravel 7.x 以前の書き方

Route::get('/home', 'HomeController@index');

これが、以下のようにネームスペース + 配列を使うようになりました。

// Laravel 8.x からの使い方

use App\Http\Controllers\HomeController;

Route::get('/home', [HomeController::class, 'index']);

ただし、実はネームスペースさえつければこれまでのような指定もOKです。(・・・がちょっと長くて見にくいですね😫)

Route::get('/home', 'App\Http\Controllers\HomeController@index');

おわりに

ということで、今回はLaravelの新バージョン8.xの内容をまとめてみました。

まだ完全にコードを試してみたわけではないですが、やはり大きな変更といえば、Jetstream(ログインまわりの機能)ですよね。

しかも、JetstreamBootstrapではなくTailwind CSSlivewireを使うなど今後のウェブ開発の方向性が少し変わってきているような気配もありますので、その辺も含めて注目していこうと思っています。

なんにせよ、ホントにLaravelの開発者たちには感謝の気持ちしかありません。よくこんなにたくさんのアイデアを実現できますね。

私がLaravel Loverでいるのは当分続きそうです。😄

ではでは〜❗

「Tailwind CSS、勉強しとこうかな・・・」

開発のご依頼お待ちしております 😊✨
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします!
このエントリーをはてなブックマークに追加       follow us in feedly  

開発効率を上げるための機材・まとめ