Laravel8で新規プロジェクトを作成する際の手順と初期設定

#0. 概要
この記事は、Laravel8で新しくプロジェクトを作る際の手順や初期設定を記したものである。Auth機能を使用しない場合は「2. Auth機能のインストール」は読み飛ばしてよい。
環境は以下の通り。
OS: windows
DB: MySQL
TE: VSCode

#1. プロジェクトの作成
コマンドプロンプトでディレクトリを移動する。ここではデスクトップに作成する。

```
cd desktop
```

移動したディレクトリ上で以下のコマンドを入力し、プロジェクトを作成する。

```
laravel new プロジェクト名
```

#2. Auth機能のインストール
##2.1. jetstreamのインストール
コマンドプロンプトで、1で作成したプロジェクト上にディレクトリを移動する。

```
cd プロジェクト名
```

移動したディレクトリ上で以下のコマンドを入力し、jetstreamをインストールする。

```
composer require laravel/jetstream
```

##2.2. livewireのインストール
以下のコマンドでlivewireをインストールする。livewireではなくinertiaをインストールする場合は、該当箇所を書き換えればよい。team機能を利用する場合は、後ろに --teamsを書き加えればよい。

```
php artisan jetstream:install livewire
```

##2.3. パッケージのビルド
以下のコマンドでパッケージをビルドする。なお、npmコマンドエラーが出る場合は事前にNode.jsをインストールしておく必要がある。

```
npm install && npm run dev
```

##2.4. 日本語化
まず、resources/langに以下のja.jsonを追加する。

```
{
    "A fresh verification link has been sent to your email address.": "新しい確認リンクを送りました。",
    "A new verification link has been sent to the email address you provided during registration.": "ご指定のメールアドレスに新しい確認リンクを送信しました。",
    "Add": "追加",
    "Add a new team member to your team, allowing them to collaborate with you.": "チームにメンバーを追加して、メンバーに協力を許可する。",
    "Add additional security to your account using two factor authentication.": "セキュリティ強化のため二段階認証を追加する。",
    "Add Team Member": "チームメンバー追加",
    "Added.": "追加完了",
    "Administrator": "管理者",
    "Administrator users can perform any action.": "管理者ユーザーはすべてのアクションを実行可能です。",
    "Age": "年齢",
    "All of the people that are part of this team.": "すべてのチームメンバー",
    "All rights reserved.": "All rights reserved.",
    "Already registered?": "登録済みの方はこちら",
    "API Token": "APIトークン",
    "API Token Permissions": "APIトークン認可",
    "API Tokens": "APIトークン",
    "API tokens allow third-party services to authenticate with our application on your behalf.": "APIトークンはサードパーティーサービスでアプリへの認証を許可します。",
    "Are you sure you want to delete this team? Once a team is deleted, all of its resources and data will be permanently deleted.": "本当にチームを削除してよろしいでしょうか？一度チームを削除すると、すべてのリソースとデータは永久に削除されます。",
    "Are you sure you want to delete your account? Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.": "本当にアカウントを削除してもよろしいでしょうか？ 一度アカウントを削除するとすべてのリソースとデータは永久に削除されます。よろしければ確認のためパスワードを入力してください。",
    "Are you sure you would like to delete this API token?": "本当にAPIトークンを削除してよろしいでしょうか？",
    "Are you sure you would like to remove this person from the team?": "本当にチームからこのメンバーを削除してよろしいでしょうか？",
    "Before proceeding, please check your email for a verification link.": "次に進む前に、確認リンクのメールをチェックしてください。",
    "Browser Sessions": "ブラウザセッション",
    "click here to request another": "ここをクリックしてメールを再送信してください。",
    "Close": "閉じる",
    "Code": "コード",
    "Confirm": "確認",
    "Confirm Password": "パスワード（確認用）",
    "Create": "作成",
    "Create a new team to collaborate with others on projects.": "プロジェクトで協力するために新しいチームを作成する。",
    "Create API Token": "APIトークン生成",
    "Create New Team": "新しいチーム作成",
    "Create Team": "チーム作成",
    "Created.": "作成完了",
    "Current Password": "現在のパスワード",
    "Dashboard": "ダッシュボード",
    "Delete": "削除",
    "Delete Account": "アカウント削除",
    "Delete API Token": "APIトークン削除",
    "Delete Team": "チーム削除",
    "Disable": "無効化",
    "Done.": "完了",
    "E-Mail Address": "メールアドレス",
    "Editor": "編集者",
    "Editor users have the ability to read, create, and update.": "編集者は読み込み、作成、更新を実行可能です。",
    "Email": "メールアドレス",
    "Email Password Reset Link": "送信",
    "Enable": "有効化",
    "Ensure your account is using a long, random password to stay secure.": "安全のため、長くてランダムなパスワードを設定するようにしてください。",
    "Error": "エラー",
    "For your security, please confirm your password to continue.": "安全のため、続行するにはパスワードの確認が必要です。",
    "Forbidden": "禁止されています",
    "Forgot your password?": "パスワードを忘れた方はこちら",
    "Forgot your password? No problem. Just let us know your email address and we will email you a password reset link that will allow you to choose a new one.": "ご登録いただいたメールアドレスを入力し、送信してください。パスワードリセット用のURLをメールにてお送りします。",
    "Go Home": "ホームへ",
    "Hello!": "こんにちは",
    "hi": "こんにちは",
    "If necessary, you may logout of all of your other browser sessions across all of your devices. Some of your recent sessions are listed below; however, this list may not be exhaustive. If you feel your account has been compromised, you should also update your password.": "すべての端末からログアウトする。最近のセッションは下記の通りです。※下記は一部表示されていない可能性があります。心配であれば、パスワードを更新してください。",
    "If you did not create an account, no further action is required.": "アカウントの作成にお心当たりが無い場合は、このメールを無視してください。",
    "If you did not receive the email": "メールが届かなかった場合",
    "If you did not request a password reset, no further action is required.": "パスワードのリセットにお心当たりが無い場合は、このメールを無視してください。",
    "If you’re having trouble clicking the \":actionText\" button, copy and paste the URL below\ninto your web browser:": "\":actionText\" ボタンが機能しない場合は, 次のURLをコピーしてWebブラウザに貼り付けてください。[:displayableActionUrl](:actionURL)",
    "Last active": "最後のログイン",
    "Login": "ログイン",
    "Log in": "ログイン",
    "Logout": "ログアウト",
    "Logout Other Browser Sessions": "すべての端末からログアウト",
    "Manage Account": "アカウント管理",
    "Manage and logout your active sessions on other browsers and devices.": "すべての端末からログアウトする。",
    "Manage API Tokens": "APIトークン管理",
    "Manage Role": "役割管理",
    "Manage Team": "チーム管理",
    "Name": "ユーザー名",
    "Nevermind": "キャンセル",
    "New Password": "新しいパスワード",
    "Oh no": "オーノー",
    "Once a team is deleted, all of its resources and data will be permanently deleted. Before deleting this team, please download any data or information regarding this team that you wish to retain.": "一度チームを削除すると、すべてのデータは永久に削除されます。削除する前に、保存しておきたいチームに関するデータまたは情報をダウンロードしてください。",
    "Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.": "一度あなたのアカウントが削除されると、すべてのデータはは永久に削除されます。削除する前に、保存しておきたいデータまたは情報をダウンロードしてください。",
    "Page Expired": "期限切れのページ",
    "Page Not Found": "ページが見つかりません",
    "Password": "パスワード",
    "Permanently delete this team.": "永久にチームを削除する。",
    "Permanently delete your account.": "永久にアカウントを削除する。",
    "Permissions": "認可",
    "Photo": "写真",
    "Please click the button below to verify your email address.": "メールアドレスを確認するには、以下のボタンをクリックしてください。",
    "Please confirm access to your account by entering one of your emergency recovery codes.": "緊急復旧コードを一つ入力し、アカウントへのアクセスを確認してください。",
    "Please confirm access to your account by entering the authentication code provided by your authenticator application.": "認証アプリから提供された認証コードを入力し、アカウントへのアクセスを確認してください。",
    "Please copy your new API token. For your security, it won't be shown again.": "新しいAPIトークンをコピーしてください。安全のため、二度と表示されません。",
    "Please enter your password to confirm you would like to logout of your other browser sessions across all of your devices.": "すべての端末からログアウトしてよければ、確認のためパスワードを入力してください。",
    "Please provide the email address of the person you would like to add to this team. The email address must be associated with an existing account.": "チームに追加したい人のメールアドレスを入力してください。メールアドレスは既存アカウントと関連づいていなければいけません。",
    "Profile": "プロフィール",
    "Profile Information": "プロフィール情報",
    "Recovery Code": "リカバリーコード",
    "Regards": "よろしくお願いします",
    "Regenerate Recovery Codes": "リカバリーコード再生成",
    "Register": "アカウント作成",
    "Remember me": "ログイン状態を保持する",
    "Remember Me": "ログイン状態を保持する",
    "Remove": "削除",
    "Remove Photo": "写真を削除",
    "Remove Team Member": "チームメンバーを削除",
    "Resend Verification Email": "確認メールを再送する",
    "Reset Password": "パスワードリセット",
    "Reset Password Notification": "パスワードリセット通知",
    "Role": "役割",
    "Save": "更新",
    "Saved.": "更新完了",
    "Select A New Photo": "新しい写真を選択",
    "Send Password Reset Link": "パスワードリセットリンクを送信",
    "Service Unavailable": "サービスは利用できません",
    "Sex": "性別",
    "Show Recovery Codes": "リカバリーコード表示",
    "Sorry, the page you are looking for could not be found.": "申し訳ありません、探しているページは見つかりませんでした。",
    "Sorry, we are doing some maintenance. Please check back soon.": "申し訳ありません、メンテナンス中です。あとでもう一度確認してください。",
    "Sorry, you are forbidden from accessing this page.": "申し訳ありません、このページへのアクセスは禁止されています。",
    "Sorry, you are making too many requests to our servers.": "申し訳ありません、一定時間内のリクエスト上限回数を超えました。",
    "Sorry, you are not authorized to access this page.": "申し訳ありません、このページにアクセスする権限がありません。",
    "Sorry, your session has expired. Please refresh and try again.": "申し訳ありません、セッションは期限切れです。更新してもう一度やり直してください。",
    "Store these recovery codes in a secure password manager. They can be used to recover access to your account if your two factor authentication device is lost.": "パスワードマネージャーにレカバリーコードを保存してください。二段階認証端末を紛失した場合にリカバリーコードでアクセスできます。",
    "Switch Teams": "チーム切り替え",
    "Team Details": "チーム詳細",
    "Team Members": "チームメンバー",
    "Team Name": "チーム名",
    "Team Owner": "チームオーナー",
    "Team Settings": "チーム設定",
    "Thanks for signing up! Before getting started, could you verify your email address by clicking on the link we just emailed to you? If you didn't receive the email, we will gladly send you another.": "登録ありがとうございます！ 開始する前に送信したリンクをクリックしてメールアドレスを確認してくれませんか？ メールを受信していない場合、メールを再送信します。",
    "The :attribute must be a valid role.": "The :attribute must be a valid role.",
    "The team's name and owner information.": "チーム名とオーナー情報",
    "This device": "この端末",
    "This password does not match our records.": "パスワードが違います。",
    "This user already belongs to the team.": "このユーザーは既にチームに所属しています。",
    "Toggle navigation": "ナビゲーションを切り替える",
    "Token Name": "トークン名",
    "Too Many Requests": "大量のリクエストがありました",
    "Two Factor Authentication": "二段階認証",
    "Two factor authentication is now enabled. Scan the following QR code using your phone's authenticator application.": "二段階認証を有効化しました。QRコードをアプリからスキャンしてください。",
    "Unauthorized": "認証が必要です",
    "Update Password": "パスワード更新",
    "Update your account's profile information and email address.": "プロフィール情報とメールアドレスを更新する。",
    "Use a recovery code": "リカバリーコードを使用する",
    "Use an authentication code": "認証コードを使用する",
    "Verify Email Address": "メールアドレスを確認してください",
    "Verify Your Email Address": "メールアドレスを確認してください",
    "We were unable to find a registered user with this email address.": "このメールアドレスは登録されていません。",
    "When two factor authentication is enabled, you will be prompted for a secure, random token during authentication. You may retrieve this token from your phone's Google Authenticator application.": "二段階認証を有効化した場合、ログイン時に安全かつランダムなトークンが与えられます。トークンはGoogle Authenticatorアプリから取得できます。",
    "Whoops, something went wrong on our servers.": "おっと、サーバーで何か問題が発生しました。",
    "Whoops!": "おっと！",
    "You are receiving this email because we received a password reset request for your account.": "パスワードリセットのリクエストを受け付けました。",
    "You have enabled two factor authentication.": "二段階認証有効化済みです。",
    "You have not enabled two factor authentication.": "二段階認証未設定",
    "You may delete any of your existing tokens if they are no longer needed.": "不要なAPIトークンを削除する。",
    "You may not delete your personal team.": "パーソナルチームを削除することはできません。",
    "You may not leave a team that you created.": "自身が作成したチームを離れることはできません。"
}
```

次に、resources/langにjaというフォルダを作成し、その中に以下の5つのファイルを置く。
auth.php

```
<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Authentication Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines are used during authentication for various
    | messages that we need to display to the user. You are free to modify
    | these language lines according to your application's requirements.
    |
    */

    'failed'   => '認証情報と一致するレコードがありません。',
    'throttle' => 'ログインの試行回数が多すぎます。:seconds 秒後にお試しください。',
];
```

pegination.php

```
<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Pagination Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines are used by the paginator library to build
    | the simple pagination links. You are free to change them to anything
    | you want to customize your views to better match your application.
    |
    */

    'previous' => '&laquo; 前',
    'next'     => '次 &raquo;',
];
```

passwords.php

```
<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Password Reminder Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines are the default lines which match reasons
    | that are given by the password broker for a password update attempt
    | has failed, such as for an invalid token or invalid new password.
    |
    */

    'reset'     => 'パスワードをリセットしました。',
    'sent'      => 'パスワードリマインダーを送信しました。',
    'throttled' => '時間を置いて再度お試しください。',
    'token'     => 'このパスワードリセットトークンは無効です。',
    'user'      => 'このメールアドレスに一致するユーザーを見つけることが出来ませんでした。',
];
```

validation-inline.php

```
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Validation Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines contain the default error messages used by
    | the validator class. Some of these rules have multiple versions such
    | as the size rules. Feel free to tweak each of these messages here.
    |
    */

    'accepted'             => 'This field must be accepted.',
    'active_url'           => 'This is not a valid URL.',
    'after'                => 'This must be a date after :date.',
    'after_or_equal'       => 'This must be a date after or equal to :date.',
    'alpha'                => 'This field may only contain letters.',
    'alpha_dash'           => 'This field may only contain letters, numbers, dashes and underscores.',
    'alpha_num'            => 'This field may only contain letters and numbers.',
    'array'                => 'This field must be an array.',
    'before'               => 'This must be a date before :date.',
    'before_or_equal'      => 'This must be a date before or equal to :date.',
    'between'              => [
        'numeric' => 'This value must be between :min and :max.',
        'file'    => 'This file must be between :min and :max kilobytes.',
        'string'  => 'This string must be between :min and :max characters.',
        'array'   => 'This content must have between :min and :max items.',
    ],
    'boolean'              => 'This field must be true or false.',
    'confirmed'            => 'The confirmation does not match.',
    'date'                 => 'This is not a valid date.',
    'date_equals'          => 'This must be a date equal to :date.',
    'date_format'          => 'This does not match the format :format.',
    'different'            => 'This value must be different from :other.',
    'digits'               => 'This must be :digits digits.',
    'digits_between'       => 'This must be between :min and :max digits.',
    'dimensions'           => 'This image has invalid dimensions.',
    'distinct'             => 'This field has a duplicate value.',
    'email'                => 'This must be a valid email address.',
    'ends_with'            => 'This must end with one of the following: :values.',
    'exists'               => 'The selected value is invalid.',
    'file'                 => 'The content must be a file.',
    'filled'               => 'This field must have a value.',
    'gt'                   => [
        'numeric' => 'The value must be greater than :value.',
        'file'    => 'The file size must be greater than :value kilobytes.',
        'string'  => 'The string must be greater than :value characters.',
        'array'   => 'The content must have more than :value items.',
    ],
    'gte'                  => [
        'numeric' => 'The value must be greater than or equal :value.',
        'file'    => 'The file size must be greater than or equal :value kilobytes.',
        'string'  => 'The string must be greater than or equal :value characters.',
        'array'   => 'The content must have :value items or more.',
    ],
    'image'                => 'This must be an image.',
    'in'                   => 'The selected value is invalid.',
    'in_array'             => 'This value does not exist in :other.',
    'integer'              => 'This must be an integer.',
    'ip'                   => 'This must be a valid IP address.',
    'ipv4'                 => 'This must be a valid IPv4 address.',
    'ipv6'                 => 'This must be a valid IPv6 address.',
    'json'                 => 'This must be a valid JSON string.',
    'lt'                   => [
        'numeric' => 'The value must be less than :value.',
        'file'    => 'The file size must be less than :value kilobytes.',
        'string'  => 'The string must be less than :value characters.',
        'array'   => 'The content must have less than :value items.',
    ],
    'lte'                  => [
        'numeric' => 'The value must be less than or equal :value.',
        'file'    => 'The file size must be less than or equal :value kilobytes.',
        'string'  => 'The string must be less than or equal :value characters.',
        'array'   => 'The content must not have more than :value items.',
    ],
    'max'                  => [
        'numeric' => 'The value may not be greater than :max.',
        'file'    => 'The file size may not be greater than :max kilobytes.',
        'string'  => 'The string may not be greater than :max characters.',
        'array'   => 'The content may not have more than :max items.',
    ],
    'mimes'                => 'This must be a file of type: :values.',
    'mimetypes'            => 'This must be a file of type: :values.',
    'min'                  => [
        'numeric' => 'The value must be at least :min.',
        'file'    => 'The file size must be at least :min kilobytes.',
        'string'  => 'The string must be at least :min characters.',
        'array'   => 'The value must have at least :min items.',
    ],
    'multiple_of'          => 'The value must be a multiple of :value',
    'not_in'               => 'The selected value is invalid.',
    'not_regex'            => 'This format is invalid.',
    'numeric'              => 'This must be a number.',
    'password'             => 'The password is incorrect.',
    'present'              => 'This field must be present.',
    'regex'                => 'This format is invalid.',
    'required'             => 'This field is required.',
    'required_if'          => 'This field is required when :other is :value.',
    'required_unless'      => 'This field is required unless :other is in :values.',
    'required_with'        => 'This field is required when :values is present.',
    'required_with_all'    => 'This field is required when :values are present.',
    'required_without'     => 'This field is required when :values is not present.',
    'required_without_all' => 'This field is required when none of :values are present.',
    'same'                 => 'The value of this field must match the one from :other.',
    'size'                 => [
        'numeric' => 'The value must be :size.',
        'file'    => 'The file size must be :size kilobytes.',
        'string'  => 'The string must be :size characters.',
        'array'   => 'The content must contain :size items.',
    ],
    'starts_with'          => 'This must start with one of the following: :values.',
    'string'               => 'This must be a string.',
    'timezone'             => 'This must be a valid zone.',
    'unique'               => 'This has already been taken.',
    'uploaded'             => 'This failed to upload.',
    'url'                  => 'This format is invalid.',
    'uuid'                 => 'This must be a valid UUID.',

    /*
    |--------------------------------------------------------------------------
    | Custom Validation Language Lines
    |--------------------------------------------------------------------------
    |
    | Here you may specify custom validation messages for attributes using the
    | convention "attribute.rule" to name the lines. This makes it quick to
    | specify a specific custom language line for a given attribute rule.
    |
    */

    'custom' => [
        'attribute-name' => [
            'rule-name' => 'custom-message',
        ],
    ],

];
```

validation.php

```
<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Validation Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines contain the default error messages used by
    | the validator class. Some of these rules have multiple versions such
    | as the size rules. Feel free to tweak each of these messages.
    |
    */

    'accepted'             => ':attributeを承認してください。',
    'active_url'           => ':attributeは、有効なURLではありません。',
    'after'                => ':attributeには、:dateより後の日付を指定してください。',
    'after_or_equal'       => ':attributeには、:date以降の日付を指定してください。',
    'alpha'                => ':attributeには、アルファベッドのみ使用できます。',
    'alpha_dash'           => ":attributeには、英数字('A-Z','a-z','0-9')とハイフンと下線('-','_')が使用できます。",
    'alpha_num'            => ":attributeには、英数字('A-Z','a-z','0-9')が使用できます。",
    'array'                => ':attributeには、配列を指定してください。',
    'before'               => ':attributeには、:dateより前の日付を指定してください。',
    'before_or_equal'      => ':attributeには、:date以前の日付を指定してください。',
    'between'              => [
        'numeric' => ':attributeには、:minから、:maxまでの数字を指定してください。',
        'file'    => ':attributeには、:min KBから:max KBまでのサイズのファイルを指定してください。',
        'string'  => ':attributeは、:min文字から:max文字にしてください。',
        'array'   => ':attributeの項目は、:min個から:max個にしてください。',
    ],
    'boolean'              => ":attributeには、'true'か'false'を指定してください。",
    'confirmed'            => ':attributeと:attribute確認が一致しません。',
    'date'                 => ':attributeは、正しい日付ではありません。',
    'date_equals'          => ':attributeは:dateに等しい日付でなければなりません。',
    'date_format'          => ":attributeの形式は、':format'と合いません。",
    'different'            => ':attributeと:otherには、異なるものを指定してください。',
    'digits'               => ':attributeは、:digits桁にしてください。',
    'digits_between'       => ':attributeは、:min桁から:max桁にしてください。',
    'dimensions'           => ':attributeの画像サイズが無効です',
    'distinct'             => ':attributeの値が重複しています。',
    'email'                => ':attributeは、有効なメールアドレス形式で指定してください。',
    'ends_with'            => ':attributeは、次のうちのいずれかで終わらなければなりません。: :values',
    'exists'               => '選択された:attributeは、有効ではありません。',
    'file'                 => ':attributeはファイルでなければいけません。',
    'filled'               => ':attributeは必須です。',
    'gt'                   => [
        'numeric' => ':attributeは、:valueより大きくなければなりません。',
        'file'    => ':attributeは、:value KBより大きくなければなりません。',
        'string'  => ':attributeは、:value文字より大きくなければなりません。',
        'array'   => ':attributeの項目数は、:value個より大きくなければなりません。',
    ],
    'gte'                  => [
        'numeric' => ':attributeは、:value以上でなければなりません。',
        'file'    => ':attributeは、:value KB以上でなければなりません。',
        'string'  => ':attributeは、:value文字以上でなければなりません。',
        'array'   => ':attributeの項目数は、:value個以上でなければなりません。',
    ],
    'image'                => ':attributeには、画像を指定してください。',
    'in'                   => '選択された:attributeは、有効ではありません。',
    'in_array'             => ':attributeが:otherに存在しません。',
    'integer'              => ':attributeには、整数を指定してください。',
    'ip'                   => ':attributeには、有効なIPアドレスを指定してください。',
    'ipv4'                 => ':attributeはIPv4アドレスを指定してください。',
    'ipv6'                 => ':attributeはIPv6アドレスを指定してください。',
    'json'                 => ':attributeには、有効なJSON文字列を指定してください。',
    'lt'                   => [
        'numeric' => ':attributeは、:valueより小さくなければなりません。',
        'file'    => ':attributeは、:value KBより小さくなければなりません。',
        'string'  => ':attributeは、:value文字より小さくなければなりません。',
        'array'   => ':attributeの項目数は、:value個より小さくなければなりません。',
    ],
    'lte'                  => [
        'numeric' => ':attributeは、:value以下でなければなりません。',
        'file'    => ':attributeは、:value KB以下でなければなりません。',
        'string'  => ':attributeは、:value文字以下でなければなりません。',
        'array'   => ':attributeの項目数は、:value個以下でなければなりません。',
    ],
    'max'                  => [
        'numeric' => ':attributeには、:max以下の数字を指定してください。',
        'file'    => ':attributeには、:max KB以下のファイルを指定してください。',
        'string'  => ':attributeは、:max文字以下にしてください。',
        'array'   => ':attributeの項目は、:max個以下にしてください。',
    ],
    'mimes'                => ':attributeには、:valuesタイプのファイルを指定してください。',
    'mimetypes'            => ':attributeには、:valuesタイプのファイルを指定してください。',
    'min'                  => [
        'numeric' => ':attributeには、:min以上の数字を指定してください。',
        'file'    => ':attributeには、:min KB以上のファイルを指定してください。',
        'string'  => ':attributeは、:min文字以上にしてください。',
        'array'   => ':attributeの項目は、:min個以上にしてください。',
    ],
    'multiple_of'          => 'The :attribute must be a multiple of :value',
    'not_in'               => '選択された:attributeは、有効ではありません。',
    'not_regex'            => ':attributeの形式が無効です。',
    'numeric'              => ':attributeには、数字を指定してください。',
    'password'             => 'パスワードが正しくありません。',
    'present'              => ':attributeが存在している必要があります。',
    'regex'                => ':attributeには、有効な正規表現を指定してください。',
    'required'             => ':attributeは、必ず指定してください。',
    'required_if'          => ':otherが:valueの場合、:attributeを指定してください。',
    'required_unless'      => ':otherが:values以外の場合、:attributeを指定してください。',
    'required_with'        => ':valuesが指定されている場合、:attributeも指定してください。',
    'required_with_all'    => ':valuesが全て指定されている場合、:attributeも指定してください。',
    'required_without'     => ':valuesが指定されていない場合、:attributeを指定してください。',
    'required_without_all' => ':valuesが全て指定されていない場合、:attributeを指定してください。',
    'same'                 => ':attributeと:otherが一致しません。',
    'size'                 => [
        'numeric' => ':attributeには、:sizeを指定してください。',
        'file'    => ':attributeには、:size KBのファイルを指定してください。',
        'string'  => ':attributeは、:size文字にしてください。',
        'array'   => ':attributeの項目は、:size個にしてください。',
    ],
    'starts_with'          => ':attributeは、次のいずれかで始まる必要があります。:values',
    'string'               => ':attributeには、文字を指定してください。',
    'timezone'             => ':attributeには、有効なタイムゾーンを指定してください。',
    'unique'               => '指定の:attributeは既に使用されています。',
    'uploaded'             => ':attributeのアップロードに失敗しました。',
    'url'                  => ':attributeは、有効なURL形式で指定してください。',
    'uuid'                 => ':attributeは、有効なUUIDでなければなりません。',

    /*
    |--------------------------------------------------------------------------
    | Custom Validation Language Lines
    |--------------------------------------------------------------------------
    |
    | Here you may specify custom validation messages for attributes using the
    | convention "attribute.rule" to name the lines. This makes it quick to
    | specify a specific custom language line for a given attribute rule.
    |
    */

    'custom' => [
        'attribute-name' => [
            'rule-name' => 'custom-message',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Custom Validation Attributes
    |--------------------------------------------------------------------------
    |
    | The following language lines are used to swap attribute place-holders
    | with something more reader friendly such as E-Mail Address instead
    | of "email". This simply helps us make messages a little cleaner.
    |
    */

    'attributes' => [],
];
```

最後に、config/app.phpで以下を変更する。

```
//変更前
'timezone' => 'UTC',
'locale' => 'en',
'faker_locale' => 'en_US',

//変更後
'timezone' => 'Asia/Tokyo',
'locale' => 'ja',
'faker_locale' => 'ja_JP',
```

#3. データベースの準備
##3.1. データベースの作成
コマンドプロンプトで以下のコマンドを実行する。

```
mysql -u root -p
```

以下のようにパスワードを求められるので、入力する。

```
Enter password: *************
```

ログインできたら、以下のコマンドでデータベースを作成する。

```
create database データベース名 character set utf8;
```

##3.2. ユーザーへの権限の付与
root権限で常にアクセスするのはセキュリティの観点から望ましくないので、新しいユーザーを作成してアクセス権限を付与するか、既にあるユーザーにアクセス権限を与えるかするためにroot権限でログインした状態から以下のコマンドを実行する。

```
grant all privileges on データベース名.* to ユーザー名@localhost identified by 'パスワード';
```

後者の場合、identified ~以降は不要である。

##3.3. .envとconfig/database.phpの修正
プロジェクト内の.envファイルをテキストエディタで開き、該当箇所を以下のように修正する。

```
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=データベース名
DB_USERNAME=ユーザー名
DB_PASSWORD=パスワード
```

同様に、config/database.phpを開いて該当箇所を以下のように修正する。

```
'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'データベース名'),
            'username' => env('DB_USERNAME', 'ユーザー名'),
            'password' => env('DB_PASSWORD', 'パスワード'),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],
```

特に、host, database, username, passwordの4つが正しいことを確認する。

##3.4. マイグレーションの実行
カレントディレクトリがプロジェクト上にあることを確認し、以下のコマンドでマイグレーションを実行する。

```
php artisan migrate
```

成功すれば、usersテーブルを含む6つのテーブルが作成されていることが確認できる。

#4. その他の設定
このままだと「Target class [〇〇] does not exist.」というエラーが出てしまうので、app/Providers/RouteServiceProvider.phpを開き、該当箇所を以下のように修正する。具体的には、「public function boot()」の上に、「protected $namespace = 'App\Http\Controllers';」を追加する。

```
protected $namespace = 'App\Http\Controllers';

public function boot()
{
    $this->configureRateLimiting();

    $this->routes(function () {
        Route::prefix('api')
            ->middleware('api')
            ->namespace($this->namespace)
            ->group(base_path('routes/api.php'));

        Route::middleware('web')
            ->namespace($this->namespace)
            ->group(base_path('routes/web.php'));
    });
}
```