sagara.inkITエンジニアのまとめノート

Laravel9がリリースされたので、あらためてLaravelというフレームワークを読み解いてみる

2022年2月8日にLaravel9がリリースされました。 composer.jsonやIlluminateの中身を読み解き、 さらに全体の処理を追いLaravelフレームワークへの理解を深めたいと思います。

Laravel概要

Laravelは言わずと知れたPHPのフレームワークです。ここ数年のPHPでフレームワークを使った開発をする場合、多くはLaravelが使われると思われます。 サーバーサイドのWebアプリケーションに必要な機能を網羅しているような高機能フレームワークです。

しかしその分全体像が見えづらく、ドキュメントを読んだだけではすべて理解することは難しいです。 つい先日Laravelの新しいバージョン9がリリースされたので、これを機にLaravelを構成する各要素についてしっかり見ていきたいと思います。

Laravelエコシステム

Laravelはフレームワーク本体に加えて、関連するパッケージ群がたくさん用意されています。 デプロイやテストなどの開発フローを容易にするものだったり、SNS認証機能など特定の機能を提供するものがあります。 これらのパッケージを含めてエコシステムと呼んでいるようです。

fig1
  • Breeze(スターターキット)
  • Cashier(決済・送金サービス連携)
  • Dusk(ブラウザ自動テスト)
  • Echo(ソケット通信)
  • Envoyer(デプロイサービス) ※有料
  • Forge(サーバー管理サービス) ※有料
  • Horizon(Redisキュー可視化)
  • Jetstream(高機能スキャフォールド)
  • Mix(Webpackアセットバンドラー)
  • Nova(UIフレームワーク) ※有料
  • Octane(アプリケーション速度向上)
  • Sail(DockerCLIラッパー)
  • Sanctum(SPA向け軽量認証システム)
  • Scout(Eloquentモデルへのテキスト全検索)
  • Socialite(SNSアカウントなどによる認証)
  • Spark(決済サービス) ※有料
  • Telescope(デバッガー)
  • Valet(MacOS向けローカル環境構築)
  • Vapor(デプロイサービス) ※有料

重要そうなものを取りあげて解説していきます。

Laravel Breeze

Starter Kits - Laravel

いわゆるスキャフォールド(scaffold)機能を提供してくれるパッケージです。 コマンドひとつ(数回)で簡単なアプリケーションの雛形をサクッと作ることができます。 学習用にサクッと試すときなどに使えそうです。 似たもので、より高機能なLaravel Jetstreamもあります。

Laravel Cashier

Laravel Cashier (Stripe) - Laravel

決済システムのStripe、送金システムのPaddleとの連携を容易にするパッケージです。

Laravel Dusk

Laravel Dusk - Laravel

ブラウザ自動テスト用パッケージです。 ブラウザ上でボタンを押すといったようなユーザーの動作を擬似的にツールが行いテストするものです。 代表的なブラウザ自動テストツールとしてはSeleniumがありますが、より簡単にブラウザテストを実施できます。

Laravel Echo

Bloadcasting - Laravel

Webソケット通信のためのJavaScriptライブラリです。HTTPの通信は一方向ですが、リアルタイム性が必要なチャット機能など双方向の通信が必要な場合があります。npmパッケージとして提供されています。

Laravel Envoyer(有料)

Envoyer - Zero Downtime PHP Deployment

ゼロダウンタイムを謳うPHP向けデプロイサービスです。 筆者は使ったことがありませんがCD(Contunious Deployment)の機能を提供しているようです。 同様の提供するサービスは他にもあるので、あえてこちらを利用する場面というのは思いつかないです。

Laravel Forge(有料)

Laravel Forge | PHP Hosting for Artisans

前述のEnvoyerと似ていますが、こちらの方が多機能なようです。 デプロイだけでなくバックアップや監視などの機能もあるサーバー管理ツールです。 Laravel公式サイトのヘッダーに独立して存在するあたり、公式からも押していきたいという意思を感じられます。

Laravel Horizon

Laravel Horizon - Laravel

キャッシュサーバーRedisへのキューをモニタリングできるツールだそうです。 アプリケーション開発においてキャッシュサーバーの中身の状態まで意識することは(筆者の経験不足により)あまりないですが、 視覚的に確認できるのはありがたいです。

Laravel Jetstream

Introduction | Laravel Jetstream

スキャフォールディング機能を提供するパッケージで、前述のBreezeよりも歴史が長いです。 認証、ユーザー登録、プロフィール編集、パスワード変更・確認、2要素認証などの機能の雛形を作ることができます。 雛形には、PHPテンプレートエンジンのBladeで雛形を作成するLivewireと、Vue.jsで雛形を作成するためのInertiaの2種類があるようです。

Laravel Mix

Compiling Assets (Mix) - Laravel

モジュールバンドラーであるWebpackのラッパーツールで、JSやCSSなどのアセットファイルをトランスパイルしたり軽量化したりなどの処理をさせることができます。 Webpackの設定ファイル(webpack.config.js)はネストが深くなりがちでやや記述が難しかったりしますが、Laravel Mixでは簡単に書くことができます(webpack.mix.js)。

LaravelプロジェクトでReactやVue.jsなどのフロントを構築するなら便利です。 laravel/laravelレポジトリのpackage.jsonにはLaravel Mixのコマンド群がデフォルトで入っています。

package.json
{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",
        "hot": "mix watch --hot",
        "prod": "npm run production",
        "production": "mix --production"
    },
    "devDependencies": {
      "laravel-mix": "^6.0.6",
      ...(省略)
  }
}

Laravel Nova(有料)

Laravel Nova

管理画面向けの綺麗なUIフレームワークです。管理画面はPHPのWebアプリケーションで作るものとしては定番です。 デザインに特別こだわらないがある程度整ったものにしたいといった時の選択肢としてありかも知れません。 とはいえ、デザイン性の高いUIフレームワークは他にもたくさんありますのであえてこれを選択するかは疑問です。

Laravel Octane

Laravel Octane - Laravel

Swooleという非同期・コルーチンな並列ネットワークエンジンを利用して、 アプリケーションのパフォーマンスを上げることができることができるそうです。

Laravel Sail

Laravel Sail - Laravel

コンテナベース仮想環境であるDockerのCLIラッパーです。 Dockerコンテナで動くLaravelアプリケーションのCLI操作がやや簡単になります。

console(通常のDockerコマンドの場合)
docker-compose up -d
docker exec -it laravel-app php artisan migrate
console(Laravel Sailの場合)
sail up -d
sail artisan migrate

laravel/laravelレポジトリにデフォルトで入っています。
sail(帆)という名前は、Dockerのコンテナを運ぶクジラ船にちなんだのでしょうか。

Laravel Sanctum

Laravel Sanctum - Laravel

ReactやVue.jsなどのSPA(Single Page Applicaion)向けに認証機能を提供するパッケージです。 APIトークンによる認証の仕組みをアプリケーションに組み込むことができます。

SPA内でユーザー認証を実装する場合はサーバーサイドのセッションが使えないため、ユーザーを識別するためのトークンを発行しユーザーのデータベースに紐付けます。

Laravel Scout

Laravel Scout - Laravel

Eloquentモデルに対してテキスト検索をかけることができるパッケージです。
モデル内でuse Searchable;することにより 全検索の処理をいちいち書くことなく実装することができるので、 フリーワード検索を実装する場面で使えるかも知れません。

Laravel Socialite

Laravel Socialite - Laravel

SNSサービスによる認証機能を提供するパッケージです。SNSアカウントによる認証機能はWebサービスと切っても切れない関係です。 Facebook、Twitter、LinkedIn、Google、GitHubといったOAuth認証サービスと連携することができます。

Laravel Spark(有料)

Laravel Spark

前述のCashierをもとに作られた決済処理サービスです。 有料サービスに必要不可欠な決済処理の実装の負担を減らし、サービスのコア機能の開発に注力することができます。

Laravel Telescope

Laravel Telescope

デバッグツールです。リクエストログやSQLクエリログなど、バグフィックスやパフォーマンス改善に役立つ様々な情報を確認することができます。

Laravel Valet

Laravel Vallet

ローカル開発環境を提供するMacOS向けのツールです。

手軽にPHPが動く環境で試すことができます。 従来からのLaravelのローカル開発環境としてはLaravel Homesteadがありますが Virtual Boxベースなのでマシンのストレージやメモリ逼迫などの懸念もあります。

これに対してValetはNginxがバックグラウンドで動くようで、メモリ消費もわずかです。 Laravel公式サイトのヘッダにはValetのみ表示含まれているのを見ると、こちらを押していきたいのかもしれません。

Laravel Vapor(有料)

Laravel Vapor

AWSのサーバレスコンピューティングであるLambdaを利用したデプロイサービスのようです。Laravel公式サイトのヘッダに独立して表示されています。

エコシステムへの所感

エコシステムの全てを利用する必要は全くない(有料サービスの宣伝も入ってる)ので、どんなパッケージがあるかだけなんとなく覚えておいて、 いざという時に調べて使えるか試してみるのがいいと思います。

  • とりあえず試したいならBreezeJetPack
  • Laravel+React/Vueな定番アプリ開発ならMixSanctum
  • SNS認証がいるならSocialite、決済機能がいるならSparkCashier
  • 開発環境がDockerならSail、そうでないMacユーザならValet
  • デバッグやパフォーマンスチューニングするならTelescope
  • デプロイを外部サービスに任せたいならVaporForge

composer.jsonからパッケージの依存関係を読み解く

Laravelのコア機能はIlluminateという名前が付けられていますが、もちろんそれ以外のPHPパッケージも多く利用しています。 composer.jsonには依存先のパッケージを読み解いていきます。

パッケージの依存関係

Laravelアプリ開発のベースとなるlaravel/laravel、およびフレームワーク本体であるlaravel/frameworkのcomposer.jsonから、 requireパッケージとrequire-devパッケージを抜き出した図が以下です。

fig1

laravel/laravelphplaravel/frameworkなど12個のパッケージに依存しています。 フレームワークの主要な機能への依存関係はlaravel/frameworkに設定されており、40個強のパッケージに依存しています。 またLaravel自体のコア機能(Illuminate、後述)についてもlaravel/frameworkに入っています。

laravel/laravelの依存先を確認

Laravelアプリ開発のベースとなるlaravel/laravelレポジトリのパッケージの依存関係を見てみます。

require

  • php
  • laravel/framework
  • laravel/scantum
  • laravel/tinker
  • fruitcake/laravel-cors
  • guzzlehttp/guzzle

phpのバージョンは2/12時点で8.0.2以降となっています。

laravel/frameworkフレームワークに依存しています。詳しくは後で見ていきます。

laravel/scantumは前述のエコシステムにもある通り、SPA向けの認証システムですね。 近年はフロントエンドにReactやVueなどのフレームワークを使うことが多いので、最初から依存関係に入っているのかも知れません。

laravel/tinkerは対話式コマンド実行環境です。PHPやLaravelのコマンドをちょっと試したい時に使えるものです。

console
php artisan tinker

余談ですが、tinkerは「いじくり回す」とか「金物修理屋」という意味らしく、ピーターパンに登場する妖精ティンカーベルの名前もここから来ているようです。

fruitcake/laravel-corsはCORS(オリジン間リソース共有)機能のミドルウェアへの実装に用いられているようです。

guzzlehttp/guzzleはHTTPクライアント機能を提供するパッケージです。guzzleは「がつがつ飲み食いする」という意味。

require-dev

  • fakerphp/faker
  • laravel/sail
  • mockery/mockery
  • nunomaduro/collision
  • phpunit/phpunit
  • spatie/laravel-ignition

fakerphp/fakerはダミーデータを生成するためのパッケージです。名前、メールアドレス、カード番号、ファイル、色、などランダムな値を生成してくれます。

laravel/sailは、前述の通りDockerCLIラッパーです。

mockery/mockeryはPHPUnitで利用するためのPHPモックを生成するパッケージです。

nunomaduro/collisionはエラーメッセージを見やすく表示するためのパッケージです。

phpunit/phpunitはテスト用フレームワークです。

spatie/laravel-ignitionはエラー画面を綺麗に表示するためのパッケージです。

FakerPHP/Faker
PHPUnit - The Testing Framework

laravel/frameworkの依存先を確認

かなりボリュームがありますが、フレームワーク本体の依存関係を見ていきましょう。

require

  • php
  • ext-mbstring
  • ext-openssl
  • doctrine/inflector
  • dragonmantank/cron-expression
  • egulias/email-validator
  • laravel/serializable-closure
  • league/commonmark
  • league/flysystem
  • monolog/monolog
  • nesbot/carbon
  • psr/container
  • psr/log
  • psr/simple-cache
  • ramsey/uuid
  • symfony/console
  • symfony/error-handler
  • symfony/finder
  • symfony/http-foundation
  • symfony/http-kernel
  • symfony/mailer
  • symfony/mime
  • symfony/process
  • symfony/routing
  • symfony/var-dumper
  • tijsverkoyen/css-to-inline-styles
  • vlucas/phpdotenv
  • voku/portable-ascii

ext-mbstringext-opensslは、PHPの拡張パッケージでそれぞれマルチバイト文字とOpenSSLを扱うためのものです。

doctrine/inflectorは、キャメルケースなどの文字変換のためのパッケージです。

dragonmantank/cron-expressionは、Cronの記述をPHPで楽に書くためのパッケージです。

egulias/email-validatorは、メールアドレスが仕様(RFC勧告)にあったものかを検証するためのパッケージです。

laravel/serializable-closureは、クロージャを安全にシリアル化するためのパッケージです。

league/commonmarkは、PHP製のMarkdownパーサです。

league/flysystemは、ファイル操作のためのパッケージです。AWS S3との連携も可能です。

monolog/monologは、ログ保存のためのパッケージです。

nesbot/carbonは、PHPで時刻に関する記述を楽にするためのパッケージです。

psr/containerpsr/logpsr/simple-chacheは、PSR(PHP標準勧告)に関するパッケージです。

ramsey/uuidは、UUIDを生成するためのパッケージです。

symfony/consolesymfony/var-dumperまでは、Laravelと同じくPHPフレームワークSymfonyのパッケージです。 LaravelはSymfonyがベースとなったフレームワークです。Symfonyに関する詳しい内容は別記事で取り上げたいと思います。

tijsverkoyen/css-to-inline-stylesは、HTMLとCSSをインライン(一行)に変換するためのパッケージです。メールで送信するために用いられるようです。

vlucas/phpdotenvは、環境変数ファイル.envの値を読み込むためのパッケージです。

voku/portable-asciiは、ASCII文字を扱うためのパッケージです。

Carbon - A simple PHP API extension for DateTime.

require-dev

  • aws/aws-sdk-php
  • doctrine/dbal
  • fakerphp/faker
  • guzzlehttp/guzzle
  • league/flysystem-aws-s3-v3
  • league/flysystem-ftp
  • league/flysystem-sftp-v3
  • mockery/mockery
  • orchestra/testbench-core
  • pda/pheanstalk
  • phpstan/phpstan
  • predis/predis
  • phpunit/phpunit
  • symfony/amazon-mailer
  • symfony/cache

既出のパッケージの説明は割愛します。

aws/aws-sdk-phpは、PHPからAWSへ連携するためのパッケージです。

doctrine/dbalは、データベース抽象化レイヤー、すなわちデータベースを抽象化してPHPで扱えるようにするためのパッケージです。

league/flysystem-aws-s3-v3は、AWSのファイルシステムであるS3と連携するためのパッケージです。

league/flysystem-ftpleague/flysystem-sftp-v3は、FTP/SFTPによるファイル転送のためのパッケージです。

orchestra/testbench-coreは、Laravelでのテストコード記述に関するパッケージです。

pda/pheanstalkは、キューシステムBeanstalkdのPHPクライアントです。

phpstan/phpstanは、PHP静的解析ツールで、実行前にエラーを検知するためのものです。

predis/predisは、キャッシュサーバーRedisのPHPクライアントです。

AWS SDK for PHP
Aws S3 (v3) Adapter - Flysystem

パッケージ依存関係についての所感

このようにLaravelは多くのパッケージのもとに成り立っています。 Laravelを普段開発するぶんにはそれほど意識することはありませんが、特にLaravelのバージョンアップやパッケージの脆弱性への対応をする際にこの辺りを見ることになることがあります。 Laravelがどのようなパッケージに依存しているかを知っておくことで、問題解決への手がかりが得られるかもしれません。

コア機能群Illuminateを読み解く

Laravelのコア機能群であるIlluminateについて見てみましょう。
laravel/frameworkレポジトリのsrc/Illuminate配下に入っています。

The Laravel Components

Illuminateは「照らす」とかいう意味ですが、Laravelには独特な名前のものが多いですね。 ちなみにWikipediaによるとLaravelという名前は「ナルニア国ものがたり」から来ているらしいです。

定義・テスト・実装を確認

実コードのすべてを読んで把握するのは骨が折れるので、 src/Illuminate/Contractにあるインターフェースの定義、test配下にあるテスト、そしてsrc/Illuminate配下の実際の実装 を見ていくことで各コンポーネントがどんな機能を提供しようとしているかを見ていきたいと思います。

  • Auth(ユーザー認証)
  • Broadcasting(ソケット通信)
  • Bus(バッチ実行)
  • Cache(キャッシュ)
  • Collections(コレクション)
  • Conditionable(クエリビルダー条件)
  • Config(設定値)
  • Console(Artisanコマンドライン)
  • Container(インスタンス保持)
  • Contracts(インターフェース群)
  • Cookie(クッキー)
  • Database(PDO、Eloquent)
  • Encryption(暗号化)
  • Events(イベント管理)
  • Filesystem(ストレージ操作)
  • Foundation(Laravelアプリケーション)
  • Hashing(ハッシュ)
  • Http(HTTPリクエスト・レスポンス)
  • Log(ロギング)
  • Macroable(Static処理付与)
  • Mail(メール送信)
  • Pagination(ページネーション)
  • Pipeline(パイプライン)
  • Queue(バックグラウンド実行)
  • Redis(Redis)
  • Routing(ルーティング)
  • Session(セッション)
  • Support(補助的なメソッド等)
  • Testing(テストコード)
  • Translation(多国地域対応)
  • Validation(バリデーション)
  • View(ビュー)

Auth

Webアプリケーションに必要不可欠な認証の仕組みを提供するコンポーネントです。 ユーザーを取得する機能、メールアドレスの検証、パスワードを変更する機能などが定義されています。

Broadcasting

ソケット通信を実現するためのコンポーネントです。 プッシュ配信用のチャンネルが取得できるか等がテストされているようです。

Bus

バッチを実行するためのコンポーネントのようです。

Collections

コレクションはLaravelのオブジェクトで、データベースのデータ等を扱うためのメソッド群が実装されています。 実際のアプリ開発でも頻繁に利用することになるコンポーネントです。

Collections - Laravel

Conditionable

データベースのクエリ条件を関数で定義することができるwhenメソッドと、その否定形であるunlessメソッドを提供するコンポーネントです。

Conditional Clauses

Cache

さまざまな種類のデータをキャッシュできるかどうかが定義・テストされています。Redisとの連携もテストされています。

Config

フレームワークに必要な設定を保持・取得するためのコンポーネントです。

Console

LaravelのコマンドラインツールであるArtisanの実装がされています。

Container

各コンポーネントのインスタンスを保持するための内部コンポーネントのようです。

Contracts

Illuminateの各コンポーネント群のインターフェースが定義されています。 ここのインターフェースに定義されているメソッド群を各コンポーネントで実装している形になります。

Cookie

クッキーを保存・取得・消去するためのコンポーネントです。 クラス名がCookieJar(クッキー瓶)という名前になっているのが可愛らしいです。

Database

各種データベースをPHPで扱うためのPDO、SQLクエリービルダー、DBスキーママイグレーション、 そしてLaravelの高機能なDBモデルクラスであるEloquentが実装されています。

Query Builder - Laravel
Eloquent ORM - Laravel

Encryption

BASE64方式による文字列の暗号化を行うコンポーネントです。

Encryption

Events

フレームワーク内でのイベントを管理するための抽象的なコンポーネントのようです。

Filesystem

ローカルストレージやS3などのクラウドストレージへのアクセスを担うコンポーネントです。

File Storage - Laravel

Foundation

Laravelアプリケーション全体を動かすための基盤となる大コンポーネントです。

Hashing

ハッシュ値の生成、同一かどうかを確認するコンポーネントです。

Hashing - Laravel

Http

HTTPリクエスト、レスポンスなどを取り扱うコンポーネントです。

HTTP Client - Laravel

Log

ログに関するコンポーネントです。内部でMonologを使っています。

Logging - Laravel

Macroable

クラスにスタティックな処理(マクロ)を追加するためのトレイトです。

Mail

メール送信に関する処理を提供するコンポーネントです。

Mail - Laravel

Notifications

メールやSlackに対応した通知のためのコンポーネントです。

Notifications - Laravel

Pagination

ページング処理に関するコンポーネントです。

Database: Pagination - Laravel

Pipeline

Containerを取得し逐次処理を行うための内部コンポーネントのようです。

Queue

ファイル操作などの重い処理をバックグラウンド実行させるためのコンポーネントです。Amazon SQSやRedisなどに対応しています。

Queues - Laravel

Redis

キャッシュサーバーRedisと連携するためのコンポーネントです。phpredis, predis等のパッケージを使用します。Redis - Laravel

Routing

Webアプリのルーティングに関する処理を提供するコンポーネントです。

Routing - Laravel

Session

セッションに関する処理を提供するコンポーネントです。データベースもしくはRedisを利用できます。

HTTP Session - Laravel

Support

アプリケーションを構築する際に必要な、補助的な機能を提供するコンポーネントです。

Testing

PHPUnitによるテストコードの機能を提供するコンポーネントです。

Testing: Getting Started - Laravel

Translation

多国地域対応に関するコンポーネントです。

Localization - Laravel

Validation

Webアプリのバリデーションに関する処理を提供するコンポーネントです。

Validation - Laravel

View

Webアプリのビューに関する処理を提供するコンポーネントです。

Views - Laravel