Laravel Advent Calendar 2020 - Qiita の 24目 の記事です。
昨日は @Lob さんのLaravel on GAE Standard 環境構築の手引きの記事でした!
明日は @mpyw さんの5年間 Laravel を使って辿り着いた,全然頑張らない「なんちゃってクリーンアーキテクチャ」という落としどころの記事です!
概要
Laravelプロジェクトをインストール直後にやった方が良さそうな初期設定をご紹介します。
ローカル環境構築
いくつも環境構築する方法はありますが、私の記事をご紹介します。
その他の手段も列挙してご紹介します。
- Herd
- Sail
- Laradock
- Vessel
- Valet
- Homestead
- XAMPP
- MAMP
- AWS Cloud9
- Vagrant & VirtualBox
- Docker
- ローカルマシンにインストール
特にどれを選択するのが正解という訳ではありません。
私の場合はDocker環境をプロジェクトに合わせて構築してます。
Laravel 初期設定
環境変数の設定
ローカル環境やステージング、本番環境で設定値を変えたい場合は環境変数ファイル(.env
)で設定します。
.env
ファイルは .gitignore
に登録されていてGit管理対象外となっています。
.env.example
ファイルを代わりに用意しておく習慣があります。
APP_NAME
APP_NAME=アプリケーション名
デフォルトは Laravel になっているので、アプリケーション名を付けてあげましょう。
APP_NAME
は主にメールやログ、セッション名で使用されてます。(変更可能)
APP_KEY
APP_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
APP_KEY
は32文字であれば何でも良かったりするのでローカルではこの値(XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
)を使ってます。
ローカル以外ではコマンドを実行して生成されたキー値を使用してください。
$ php artisan key:generate
LOG_*
Laravelでは標準で様々なログ機能が備わっています。
環境変数で設定を切り替えできます。
ログの詳細設定は config/logging.php
ファイルを確認してください。
下記、ログのチャンネル設定を抜粋しています。
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single'],
'ignore_exceptions' => false,
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 14,
],
'stderr' => [
'driver' => 'monolog',
'level' => env('LOG_LEVEL', 'debug'),
'handler' => StreamHandler::class,
'formatter' => env('LOG_STDERR_FORMATTER'),
'with' => [
'stream' => 'php://stderr',
],
],
],
デフォルト stack
チャンネルが使用されています。複数のチャンネルへログを出力できます。
single
のみ設定されているので storage/logs/laravel.log
に生成されます。
補足: コンテナログを出力する
'stack' => [
'driver' => 'stack',
'channels' => ['single', 'stderr'], // 追加
'ignore_exceptions' => false,
],
'stderr' => [
'driver' => 'monolog',
'level' => env('LOG_LEVEL', 'debug'),
'handler' => StreamHandler::class,
'formatter' => env('LOG_STDERR_FORMATTER', 'Monolog\\Formatter\\JsonFormatter'),
'with' => [
'stream' => 'php://stderr',
],
],
stderr
チャンネルはログを標準出力します。
Dockerを使ってる場合はコンテナログから確認できます。
$ docker compose logs
docker-laravel-app-1 | [07-Oct-2022 08:32:11] NOTICE: fpm is running, pid 1
docker-laravel-app-1 | [07-Oct-2022 08:32:11] NOTICE: ready to handle connections
docker-laravel-app-1 | [2022-10-07 08:33:04] local.DEBUG: test
docker-laravel-app-1 | 172.23.0.4 - 07/Oct/2022:08:33:03 +0000 "GET /index.php" 200
標準出力のログをJSON形式で吐き出したい時は formatter
に Monolog\\Formatter\\JsonFormatter
を指定します。
$ docker compose logs
docker-laravel-app-1 | [07-Oct-2022 08:34:32] NOTICE: fpm is running, pid 1
docker-laravel-app-1 | [07-Oct-2022 08:34:32] NOTICE: ready to handle connections
docker-laravel-app-1 | {"message":"test","context":{},"level":100,"level_name":"DEBUG","channel":"local","datetime":"2022-10-07T08:34:40.571610+00:00","extra":{}}
docker-laravel-app-1 | 172.23.0.4 - 07/Oct/2022:08:34:39 +0000 "GET /index.php" 200
デイリーログ
daily
チャンネルは日毎にログファイルを分けて出力します。
'stack' => [
'driver' => 'stack',
'channels' => ['daily', 'stderr'], // 追加
'ignore_exceptions' => false,
],
DB_*
ローカル用のDB接続情報も予めプロジェクトで決まってることも多いと思うので設定しておきましょう。
データベースの詳細設定は config/database.php
ファイルを確認してください。
DB_CONNECTION=mysql
#DB_HOST=db
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=phper
DB_PASSWORD=secret
DB_HOST
はDocker ComposeなどでDBコンテナを作っていればサービス名を指定できます。
それ以外ではホスト名またはIPアドレスを指定します。
SESSION_*
セッション設定はプロジェクトによると思いますが、最低限設定した方が良い項目をご紹介します。
ログの詳細設定は config/session.php
ファイルを確認してください。
SESSION_LIFETIME=10080
SESSION_LIFETIME
デフォルトは2時間(120分)です。
ローカルは1週間(10080分)と長めに設定しておくと良いです。
環境変数をconfigファイルへ移行
環境変数はdocker-compose.ymlだったりDockerfileだったり、.envだったりconfig/*.phpと色んなところで設定できます。
しかし定義する場所がとっ散らかってると最終的にどこの値が設定されているのか分かりにくいです。
ローカル環境の設定をデフォルト値としてすべて config/*.php
へ移行します。
Laravelプロジェクトをインストールしてから.envに何も追加してなければ下記のファイルの初期値を確認すればokです。
(.envとconfig/*.phpで若干デフォルト値に差異があるものありました。)
- config/app.php
- config/broadcasting.php
- config/database.php
- config/logging.php
- config/mail.php
- config/session.php
タイムゾーン、言語設定
Laravelのアプリ設定でタイムゾーン&言語設定します。
日本のシステムではれば日本語化しておきましょう。
return [
// アプリケーションデフォルトのタイムゾーンを設定できます。
// PHPの日付および日時関数を使用する際にこの設定を参照します。
'timezone' => 'Asia/Tokyo',
// 翻訳サービスプロバイダーが使用するデフォルトのロケールを設定します。
'locale' => 'ja',
// フォールバックロケールは、指定したロケールが使用できない場合に使用するロケールを決定します。
'fallback_locale' => 'ja',
// FakerPHPライブラリがデータを生成する際に使用されます。
'faker_locale' => 'ja_JP',
],
データベースの文字コード、照合順序の設定(MySQL8.0.2以降の使用例)
データベース設定は config/database.php
ファイルで行います。
要件に応じて設定します。
return [
'connections' => [
'mysql' => [
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_bin',
],
],
];
文字コード utf8mb4
は1文字最大4バイトを使用し、絵文字をサポートしてます。
照合順序 utf8mb4_bin
はアクセント記号(清音濁音半濁音)、大文字小文字(拗音促音など)、ひらがなとカタカナを判別します。
照合順序 | はは ≠ ハハ | びょういん ≠ びよういん | はは ≠ ぱぱ | ハハ ≠ ハハ | A ≠ a | 🍣 ≠ 🍺 | 備考 |
---|---|---|---|---|---|---|---|
utf8mb4_bin | T | T | T | T | T | T | |
utf8mb4_general_ci | T | T | T | T | F | F | 5.7 default |
utf8mb4_0900_ai_ci | F | F | F | F | F | T | 8.0 default |
utf8mb4_0900_as_ci | F | F | T | F | F | T | |
utf8mb4_0900_as_cs | T | T | T | T | T | T | |
utf8mb4_ja_0900_as_cs | F | T | T | F | T | T | |
utf8mb4_ja_0900_as_cs_ks | T | T | T | F | T | T |
照合順序はプロジェクトや機能要件に合わせて選定していきましょう。
参考サイト)
https://dev.mysql.com/blog-archive/mysql-8-0-kana-sensitive-collation-for-japanese-ja_jp/
https://zenn.dev/zoeponta/articles/090c68ba820a24
公開ディスクのシンボリック設定
ファイルストレージ設定は config/filesystems.php
ファイルで行います。
$ php artisan storage:link
public/storage
から storage/app/public
にシンボリックリンクを作成します。
これによりウェブアクセスからファイルを参照できます。
N+1検出設定
Laravel 9.35 以降の新機能です。
本番環境では無効化されますし、N+1をすぐ検出できるので入れて損はない機能です。
- https://github.com/laravel/framework/pull/44283
- https://github.com/laravel/framework/blob/9.x/src/Illuminate/Database/Eloquent/Model.php#L401-L412
- https://laravel-news.com/laravel-9-35-0
- https://zenn.dev/nshiro/articles/eb71996064a891
<?php
declare(strict_types=1);
namespace App\Providers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\ServiceProvider;
final class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
Model::shouldBeStrict(! $this->app->isProduction());
}
}
3つの機能が有効化されます。
- モデルのリレーションの遅延ロード(N+1)を検出し、例外を発生させる
- 開発時はデータ量が少なく、Laravelに不慣れだと実際にSQLログを見てみないとN+1なってるかは気付きにくいです。
- 往々にして本番想定テストを始めた段階の開発終盤で気付くことになってしまうので予め有効にするのが吉。
- モデルの
$fillable
や$guarded
で許可されてない属性へ代入した場合に例外を発生させる- 設定しない場合は
null
が入ってしまっていたため、nullableなカラムだと問題に気付きにくかった。
- 設定しない場合は
- 取得したモデルの存在しない属性へアクセスした場合に例外を発生させる
- 今までは null を返していたため、単にデータがないだけだと勘違いしてしまう場合があった。
日本語翻訳ファイルの取得
デフォルトで用意されている言語ファイルは下記のファイルです。
- lang/en.json
- lang/en/auth.php
- lang/en/pagination.php
- lang/en/passwords.php
- lang/en/validation.php
※Laravel9以降 resources/lang
から lang
にディレクトリ構成が変更されました。
この言語ファイルに対応する各言語の翻訳ファイルは下記のリポジトリで管理されています。
Laravelプロジェクトルートで下記のコマンドを実行してください。
$ composer require --dev laravel-lang/lang laravel-lang/publisher
$ php artisan lang:add ja
日本語の翻訳ファイルを追加します。
インストール後はライブラリ不要なのでアンインストールしてOKです。
$ composer remove --dev laravel-lang/lang laravel-lang/publisher
composer.json 基本情報
{
"name": "your-vendor-name/your-project-name",
"type": "project",
"description": "プロジェクトの説明",
"license": "proprietary",
}
プロジェクト名、プロジェクトの説明を記載します。
ライセンスは社内のプライベートな開発であれば proprietary
と明示しておきましょう。
composer.jsonのPHPバージョン指定
composer.json
のPHPのバージョンを指定します。
{
"require": {
"php": "^7.3|^8.0",
...
},
...
}
PHP8.1系を利用している場合は下記のように設定するとIDE補完が正しく機能します。
{
"require": {
"php": "^8.1",
...
},
...
}
composer.jsonの不要なscriptsの削除
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-update-cmd": [
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
],
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
]
},
post-root-package-install
と post-create-project-cmd
は composer create-project
コマンド実行時に呼び出されれます。
Laravelプロジェクトインストール後は使用されないスクリプトになるので削除してOKです。
Node関連設定
package.json
package.json
は composer.json
のNode版に当たります。
Nodeのライブラリのバージョン管理をするファイルです。
現時点(9.35.1
)のデフォルトは下記になります。
{
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build"
},
"devDependencies": {
"axios": "^0.27",
"laravel-vite-plugin": "^0.6.0",
"lodash": "^4.17.19",
"postcss": "^8.1.14",
"vite": "^3.0.0"
}
}
パッケージ管理ツールの選定
npm
, yarn
, pnpm
のいずれかを利用することになると思います。
どれを使うかはプロジェクトによりますが、今回は npm
を使用する例です。
npm
を使用する場合、ロックファイルは package-lock.json
となります。
使用しないツールのロックファイルをGit管理対象外にします。
yarn.lock
pnpm-lock.yaml
Nodeバージョンとライブラリを強制する
Nodeのv18系で実行して欲しい時は package.json
に engines
フィールドを追加します。
engine-strict=true
"engines": {
"node": "18.12.0",
"yarn": "Don't use yarn, Use npm",
"pnpm": "Don't use pnpm, Use npm"
}
また、メジャーバージョンだけ固定したい場合は 18.x
と指定できます。
Nodeバージョンの切り替えファイル
nodenv を利用している場合、.node-version
ファイルが置かれていると自動的にそのバージョンに切り替えてくれます。
18.12.0
Renovate の導入
古くなったライブラリを自動更新してくれるツールです。
入れておいて損はないのでプロジェクト作成したらすぐ導入することを推奨します。
各種ライブラリがアップデートされると自動的にプルリクを作ってくれます。
バージョンが古くなるとアップデート作業が大変になるので、定期的にマージしていく運用にしましょう。
Editorconfig の導入
エディタの文字コード、改行コード、インデント設定を統一してくれるツールです。
Laravelプロジェクトにはあらかじめ .editorconfig 設定ファイルが入っています。
各自使用しているエディタへプラグインをインストールすればすぐ利用できます。
プラグインのダウンロードはこちらから。
https://editorconfig.org/#download
Laravel IDE Helper 自動補完ツールの導入
IDEのオートコンプリート機能が正しく動作するためのヘルパーファイルを生成するツールです。
これがあると開発UX上がるので入れておくと良いです。
Laravel IDE Helper インストール
$ composer require --dev barryvdh/laravel-ide-helper
Laravel IDE Helper 使い方
# Facade用のPHPDocを生成する(_ide_helper.php)
$ php artisan ide-helper:generate
# Model用のPHPDocsを生成する(_ide_helper_models.php)
$ php artisan ide-helper:models
# PhpStorm用のメタファイルを生成する(.phpstorm.meta.php)
$ php artisan ide-helper:meta
ide-helper:models 補足
ide-helper:models
コマンドを実行するとモデルに直接phpdocを生成するか、_ide_helper_models.php
に生成するか質問されます。
選択しないでEnterすると_ide_helper_models.php
が生成されます。
$ php artisan ide-helper:models
Do you want to overwrite the existing model files? Choose no to write to _ide_helper_models.php instead (yes/no) [no]:
>
質問ではなく、コマンドオプションで選択できます。
# モデルに生成
$ php artisan ide-helper:models --write
# _ide_helper_models.phpに生成
$ php artisan ide-helper:models --nowrite
_ide_helper_models.php
に生成するデメリットとしては、PhpStormでコードジャンプすると二重警告でジャンプ先が二つ表示されてしまうことです。
逆にモデルに直接生成する場合はコンフリクトが発生する懸念があります。
自分のオススメとしてはモデルに生成する方が良いかもと思います。
$ php artisan ide-helper:models --write --reset
--write
オプションでは、テーブルカラムの情報もphpdocが追記されていきます。
phpdoc生成後に新たにテーブルカラムを追加した場合も最後に追記されていきます。
--reset
オプションでphpdocを削除してから生成し直すので順番もテーブルの定義順に並べてくれます。
Laravel IDE Helper .gitignore に追記
IDE Helperで生成されたファイルはGitで管理する必要がないのでGit管理対象外にします。
$ echo _ide_helper.php >> .gitignore
$ echo _ide_helper_models.php >> .gitignore
$ echo .phpstorm.meta.php >> .gitignore
コード自動整形ツールの導入
設定したルールに従って、ソースコードを整形するツールを入れるととても便利です。
インデントが崩れてる等、コードレビューでコードスタイル周りで指摘することが激減します。
Laravel v9.3.0からLaravel PintというPHP-CS-Fixerのラッパーライブラリが標準搭載されています。
それぞれ個別の記事で紹介してます。
Laravel Pint
https://qiita.com/ucan-lab/items/8807a092eb6d87ddfe34
Laravel Pint 自動実行
https://qiita.com/ucan-lab/items/be809da727fe698bb390
PHP-CS-Fixer
https://qiita.com/ucan-lab/items/7d4180462347a42009d5
larastan 静的解析ツールの導入
Larastanは静的解析ツールPHPStanのLaravel用のラッパーライブラリです。
詳細は別記事にまとめました。
PHP Insightsのインストール
コード品質分析ツールです。
詳細は別記事にまとめました。
GitHub Actions CI設定
初期設定の段階で自動テストを設定しておくと良いです。
テストしたい内容はプロジェクトにより異なると思いますが、以前に記事を書きましたのでよければ参考ください。
Laravel Dacapo マイグレーションサポートツールの導入
手前味噌ですが、マイグレーションをYAMLでシンプルに定義できるツールを作成しています。
乱れがちなマイグレーションファイルを綺麗な状態に保ちながら開発が行えます。
Doctrine DBAL スキーマ管理ツールの導入
マイグレーションファイルにカラム変更のマイグレーションを定義する際に必要となるツールです。
Laravel Dacapoを使用している間は不要ですが、運用始まったとはカラム変更は必ず入ってくると思うので予めインストールしておくと良いです。
$ composer require doctrine/dbal
MailHog SMTPテストツールの導入
ローカルにSMTPサーバーを構築して、送信したメールをWebUIで表示してくれるツールです。
Docker Hubに公式イメージが上がってるので、Dockerを使ってると簡単に導入できます。
私のDocker Laravelテンプレートリポジトリにも導入してます。
メール送信の動作確認は下記のコマンドを実行します。
$ php artisan tinker
Mail::raw('test mail',function($message){$message->to('test@example.com')->subject('test');});
データベースクリアシーダーの作成
php artisan db:seed
でシーダー実行時にテーブルをすべて初期化したい場合、
正しい順序でtruncate
を仕込んだり、外部キー制約を都度有効/無効化する必要がでてきます。
シーダーファイルが複雑化してしまうので、すべてのテーブルをクリアするシーダーファイルを作っておくとシーダーファイル作成が楽になります。
マイグレーションファイルが増えてくると php artisan migrate:fresh
も時間がかかってくるため。
テスト関連
CSRFトークン検証のミドルウェアを無効化する
HTTPテストでPOSTメソッドを実行する場合 Expected status code 200 but received 419 with Laravel
とCSRFトークンのチェックで弾かれてしまいます。
テスト時は CSRFトークンの検証は無効化します。
<?php
declare(strict_types=1);
namespace App\Http\Middleware;
use Closure;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
use Illuminate\Http\Request;
use Illuminate\Session\TokenMismatchException;
final class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array<int, string>
*/
protected $except = [];
/**
* Handle an incoming request.
*
* @param Request $request
* @param Closure $next
* @return mixed
* @throws TokenMismatchException
*/
public function handle($request, Closure $next): mixed
{
if (app()->environment() !== 'testing') {
return parent::handle($request, $next);
}
return $next($request);
}
}
GitHub リポジトリ設定
- Issue, PullRequestテンプレート
- 使用するマージボタンの選定
- 自動マージを許可する設定
- マージ済みブランチの自動削除設定
- ブランチ保護ルール設定
- .gitignore
- https://github.com/github/gitignore/blob/main/Laravel.gitignore
- 参考にプロジェクト用の設定ファイルを記述する
- README.md
- プロジェクト、ツールの使い方、インストール方法などをまとめておく
- わかりやすいREADME.mdを書く
- SECURITY.md
- セキュリティポリシーを設定する
GitHub作ったらなるべく早めに設定しておきましょう。
OpenAPI Generator APIドキュメント生成ツール
API開発時は活用するとフロント側のAPI連携が楽になります。
デバッグツールの導入
- とりあえず入れておくデバッグツール https://github.com/beyondcode/laravel-dump-server
- Blade開発時のデバッグツール https://github.com/barryvdh/laravel-debugbar
- API開発時のデバッグツール https://readouble.com/laravel/9.x/ja/telescope.html
プロジェクト開発初期に実装する機能
プロジェクトの開発初期に実装する機能を記事にまとめています。
仕様によって実装内容は変わると思いますがご参考になれば幸いです。
Laravel便利機能