LoginSignup
112
98

Laravelプロジェクトの初期設定

Last updated at Posted at 2020-12-24

Laravel Advent Calendar 2020 - Qiita の 24目 の記事です。
昨日は @Lob さんのLaravel on GAE Standard 環境構築の手引きの記事でした!
明日は @mpyw さんの5年間 Laravel を使って辿り着いた,全然頑張らない「なんちゃってクリーンアーキテクチャ」という落としどころの記事です!

概要

Laravelプロジェクトをインストール直後にやった方が良さそうな初期設定をご紹介します。

ローカル環境構築

いくつも環境構築する方法はありますが、私の記事をご紹介します。

その他の手段も列挙してご紹介します。

特にどれを選択するのが正解という訳ではありません。
私の場合はDocker環境をプロジェクトに合わせて構築してます。

Laravel 初期設定

環境変数の設定

ローカル環境やステージング、本番環境で設定値を変えたい場合は環境変数ファイル(.env)で設定します。
.env ファイルは .gitignore に登録されていてGit管理対象外となっています。
.env.example ファイルを代わりに用意しておく習慣があります。

APP_NAME

.env
APP_NAME=アプリケーション名

デフォルトは Laravel になっているので、アプリケーション名を付けてあげましょう。
APP_NAME は主にメールやログ、セッション名で使用されてます。(変更可能)

APP_KEY

.env
APP_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

APP_KEY は32文字であれば何でも良かったりするのでローカルではこの値(XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX)を使ってます。
ローカル以外ではコマンドを実行して生成されたキー値を使用してください。

$ php artisan key:generate

LOG_*

Laravelでは標準で様々なログ機能が備わっています。
環境変数で設定を切り替えできます。

ログの詳細設定は config/logging.php ファイルを確認してください。
下記、ログのチャンネル設定を抜粋しています。

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 に生成されます。

補足: コンテナログを出力する
config/logging.php
        '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形式で吐き出したい時は formatterMonolog\\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 チャンネルは日毎にログファイルを分けて出力します。

config/logging.php
        'stack' => [
            'driver' => 'stack',
            'channels' => ['daily', 'stderr'], // 追加
            'ignore_exceptions' => false,
        ],

DB_*

ローカル用のDB接続情報も予めプロジェクトで決まってることも多いと思うので設定しておきましょう。
データベースの詳細設定は config/database.php ファイルを確認してください。

.env.example
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 ファイルを確認してください。

.env.example
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のアプリ設定でタイムゾーン&言語設定します。
日本のシステムではれば日本語化しておきましょう。

config/app.php
return [
    // アプリケーションデフォルトのタイムゾーンを設定できます。
    // PHPの日付および日時関数を使用する際にこの設定を参照します。
    'timezone' => 'Asia/Tokyo',

    // 翻訳サービスプロバイダーが使用するデフォルトのロケールを設定します。
    'locale' => 'ja',

    // フォールバックロケールは、指定したロケールが使用できない場合に使用するロケールを決定します。
    'fallback_locale' => 'ja',

    // FakerPHPライブラリがデータを生成する際に使用されます。
    'faker_locale' => 'ja_JP',
],

データベースの文字コード、照合順序の設定(MySQL8.0.2以降の使用例)

データベース設定は config/database.php ファイルで行います。
要件に応じて設定します。

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をすぐ検出できるので入れて損はない機能です。

app/Providers/AppServiceProvider.php
<?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 基本情報

composer.json
{
    "name": "your-vendor-name/your-project-name",
    "type": "project",
    "description": "プロジェクトの説明",
    "license": "proprietary",
}

プロジェクト名、プロジェクトの説明を記載します。
ライセンスは社内のプライベートな開発であれば proprietary と明示しておきましょう。

composer.jsonのPHPバージョン指定

composer.json のPHPのバージョンを指定します。

composer.json
{
    "require": {
        "php": "^7.3|^8.0",
        ...
    },
    ...
}

PHP8.1系を利用している場合は下記のように設定するとIDE補完が正しく機能します。

composer.json
{
    "require": {
        "php": "^8.1",
        ...
    },
    ...
}

composer.jsonの不要なscriptsの削除

composer.json
    "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-installpost-create-project-cmdcomposer create-project コマンド実行時に呼び出されれます。
Laravelプロジェクトインストール後は使用されないスクリプトになるので削除してOKです。

Node関連設定

package.json

package.jsoncomposer.json のNode版に当たります。
Nodeのライブラリのバージョン管理をするファイルです。

現時点(9.35.1)のデフォルトは下記になります。

package.json
{
    "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管理対象外にします。

.gitignore
yarn.lock
pnpm-lock.yaml

Nodeバージョンとライブラリを強制する

Nodeのv18系で実行して欲しい時は package.jsonengines フィールドを追加します。

.npmrc
engine-strict=true
package.json
  "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 ファイルが置かれていると自動的にそのバージョンに切り替えてくれます。

.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');});

ScreenShot 2022-09-17 17.14.43.png

データベースクリアシーダーの作成

php artisan db:seed でシーダー実行時にテーブルをすべて初期化したい場合、
正しい順序でtruncateを仕込んだり、外部キー制約を都度有効/無効化する必要がでてきます。

シーダーファイルが複雑化してしまうので、すべてのテーブルをクリアするシーダーファイルを作っておくとシーダーファイル作成が楽になります。
マイグレーションファイルが増えてくると php artisan migrate:fresh も時間がかかってくるため。

テスト関連

CSRFトークン検証のミドルウェアを無効化する

HTTPテストでPOSTメソッドを実行する場合 Expected status code 200 but received 419 with Laravel とCSRFトークンのチェックで弾かれてしまいます。

テスト時は CSRFトークンの検証は無効化します。

app/Http/Middleware/VerifyCsrfToken.php
<?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 リポジトリ設定

GitHub作ったらなるべく早めに設定しておきましょう。

OpenAPI Generator APIドキュメント生成ツール

API開発時は活用するとフロント側のAPI連携が楽になります。

デバッグツールの導入

プロジェクト開発初期に実装する機能

プロジェクトの開発初期に実装する機能を記事にまとめています。
仕様によって実装内容は変わると思いますがご参考になれば幸いです。

Laravel便利機能

112
98
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
112
98