Closed12

Laravelのドキュメントを読む🧐

まさとまさと

基礎

  • ルーティング
  • ミドルウェア
  • CSRF保護
  • コントローラ
  • リクエスト
  • レスポンス
  • ビュー
  • Bladeテンプレート
  • アセットの構築
  • URL生成
  • セッション
  • バリデーション
  • エラー処理
  • ログ
まさとまさと

ルーティング

  • routesディレクトリにあるファイルで定義する
    • App\Providers\RouteServiceProviderによって自動的に読み込まれる
    • web.phpはWebインターフェース用, api.phpはステートレスで、それぞれに適したミドルウェアが割り当てられている
    • apiは自動的に/apiプレフィックスが自動的に適用される
  • Routeを使用して、HTTPメソッドに応答するルーティングを登録できる
    • 複数のメソッドに対応するmatch, anyがある
  • コールバックの引数に依存関係を指定することで、サービスコンテナが自動的に解決してくれる
  • ↓HTTPリクエストの注入している
use Illuminate\Http\Request;

Route::get('/users', function (Request $request) {
    // ...
});
  • webルートで定義したルートに送るHTMLフォームには、CSRFトークンフィールド(@csrf)を含める必要がある

  • redirectメソッドでリダイレクト・ステータスコードの指定もできる

  • viewメソッドでviewを返せる

    • データを配列で指定できる
  • php artisan route:listで定義されているルートの概要を表示できる

php artisan route:list -vv

  GET|HEAD   / ................................................................................................................................................................................................... 
             ⇂ App\Http\Middleware\EncryptCookies
             ⇂ Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse
             ⇂ Illuminate\Session\Middleware\StartSession
             ⇂ Illuminate\View\Middleware\ShareErrorsFromSession
             ⇂ App\Http\Middleware\VerifyCsrfToken
             ⇂ Illuminate\Routing\Middleware\SubstituteBindings
  POST       _ignition/execute-solution ............................................................................................ ignition.executeSolution › Spatie\LaravelIgnition › ExecuteSolutionController
             ⇂ Spatie\LaravelIgnition\Http\Middleware\RunnableSolutionsEnabled
  GET|HEAD   _ignition/health-check ........................................................................................................ ignition.healthCheck › Spatie\LaravelIgnition › HealthCheckController
             ⇂ Spatie\LaravelIgnition\Http\Middleware\RunnableSolutionsEnabled
  POST       _ignition/update-config ..................................................................................................... ignition.updateConfig › Spatie\LaravelIgnition › UpdateConfigController
             ⇂ Spatie\LaravelIgnition\Http\Middleware\RunnableSolutionsEnabled
  GET|HEAD   api/user ............................................................................................................................................................................................ 
             ⇂ App\Http\Middleware\Authenticate:sanctum
             ⇂ Illuminate\Routing\Middleware\ThrottleRequests:api
             ⇂ Illuminate\Routing\Middleware\SubstituteBindings
  GET|HEAD   sanctum/csrf-cookie ............................................................................................................... sanctum.csrf-cookie › Laravel\Sanctum › CsrfCookieController@show
             ⇂ App\Http\Middleware\EncryptCookies
             ⇂ Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse
             ⇂ Illuminate\Session\Middleware\StartSession
             ⇂ Illuminate\View\Middleware\ShareErrorsFromSession
             ⇂ App\Http\Middleware\VerifyCsrfToken
             ⇂ Illuminate\Routing\Middleware\SubstituteBindings

                                                                                                                                                                                                Showing [6] routes
  • '/user{id}'のようなルートの場合、コールバックの引数に(string $id)とすることでURLからIDを取得できる
    • 依存性注入の後に書く(ある場合は)
    • ?をつけるとオプションパラメータになる
      • '/user/{name?}', function (?string $name = null)
    • 正規表現を使用することで、ルートパラメータを制限することが可能
      • よく使う正規表現のパターンはインスタンスのメソッドで用意されている
    • 常にルートパラメータを特定の正規表現で制限したい場合は、patternメソッドを使用する
      • RouteServiceProviderのbootメソッドで
  • /をパラメータ内で使用したい場合は、whereを使用する
Route::get('/search/{search}', function (string $search) {
    return $search;
})->where('search', '.*');
  • ->name('hoge')とすることで、ルートの名前を指定できる

    • 名前付きルートを使用することでリダイレクト先やViewのフォームの送信先の指定に使える
  • ルートグループを使用すると、複数のルートで色々共有できる

    • ミドルウェア
    • コントローラー
    • サブドメイン
    • プレフィックス
    • ルート名のプレフィックス
      • name()でルートの指定を便利にできる
  • ルートモデル結合

    • タイプヒントの変数名とルートセグメント名が一致した場合、ルート or コントローラーで定義したEloquentモデルを自動的に解決する
    • id以外でも可能
    • モデルが見つからなかった場合の動作もカスタマイズ可能
  • Enumsもサポート

  • RouteServiceProviderに定義することで、Laravelの命名規則ベースではないモデルの解決も可能

use App\Models\User;

Route::get('/users/{user}', function (User $user) {
    return $user->email;
});
  • フォールバックルート

    • Route:fallback()でリクエストが全ルートに一致しなかった場合に実行するルートを定義できる
      • 常に最後に指定する必要がある
  • レート制限

    • RateLimiterファサードを使用することで、レート制限が可能
      • byメソッドによってセグメント化も可能
      • 複数のレート制限も可能
      • throttleミドルウェアを使用することでルートに適用する
        • キャッシュドライバとしてRedisを使用している場合は、ThrottleRequestsWithRedisを使用した方が良さげ
      • ↓でルートに適用する
Route::middleware(['throttle:uploads'])->group(function () {
    Route::post('/audio', function () {
        // ...
    });
  • 擬似フォームメソッド
    • HTMLフォームではPUT・PATCH・DELETEがサポートされていない
    • 上記のルートを定義する際には、↓のように_methodを追加して対応する
<form action="/example" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>

// or

<form action="/example" method="POST">
    @method('PUT')
    @csrf
</form>
  • Routeファサードのcurrent, currentRouteName, currentRouteActionメソッドを使用するとリクエストを処理するルートに関する情報にアクセスできる
public function test(Request $request)
    {
        dd(Route::current());
    }
↓
Illuminate\Routing\Route {#231 ▼ // app/Http/Controllers/TestController.php:12
  +uri: "test"
(省略)

dd(Route::currentRouteName());null

dd(Route::currentRouteAction());"App\Http\Controllers\TestController@test" 
  • CORS

    • config/cors.phpでCORSの設定が可能
      • 異なるオリジンからのリクエストを設定できる
  • ルートキャッシュを使用して、ルートの登録時間を短縮できる

    • php artisan route:cache
まさとまさと

ミドルウェア

  • HTTPリクエストを検査・フィルタリングするためのメカニズムを提供
    • app/Http/Middlwareにある
    • リクエストがミドルウェアの処理をパスできなければリダイレクト
    • パスできれば$next($request)で次の処理を呼び出す
      • ↑をreturnするタイミングによっては、間に他の処理を挟むことも可能
  • ミドルウェアはサービスコンテナを介して依存解決される
  • 自作できる
  • 全てのHTTPリクエストに対して実行する場合はapp/Http/Kernel.php$middleware配列に登録する
  • 特定のルートに対してはmiddlewareメソッドを呼び出す
    • エイリアスを割り当てておくと呼び出し時に便利(Kenelで登録できる)
  • グループに対してミドルウェアを適用することもでき、グループ内の特定のルートではミドルウェアを実行しないようにすることも可能
  • 複数のミドルウェアをグループ化してルートへ割り当てられる
    • $middlewareGroupsプロパティをに定義・追加する
      • デフォルトではwebapiに適用するミドルウェアが定義されている
  • $middlewarePriorityプロパティでミドルウェアの実行順を指定できる
  • ミドルウェア名:パラメータとすることでミドルウェアにパラメータを渡すことができる
  • レスポンスがブラウザに送信されたあとにミドルウェアで何らかの処理を実行したい
    • terminateメソッドが自動的に呼ばれる
    • 同じインスタンスを使用する場合は、AppServiceProvidersingletonとして登録すると良い
まさとまさと

CSRF保護

  • 認証済みユーザーに代わって不正なコマンドを実行する攻撃
  • LaravelはアクティブなユーザーセッションごとにCSRFトークンを生成する
    • 認証済みのユーザーが実際にアプリケーションにリクエストをしているかをチェックするため
  • CSRFトークンの確認はApp/Http/Middleware/VerifyCsrfToken.phpがやってる
  • SPAやモバイルアプリのAPIとしてLaravelを使っている場合は、Sanctumが便利らしい
  • CSRF保護をしたくない場合、VerifyCsrfTokenミドルウェアの$exceptにURIを追加する
  • POSTパラメータのCSRFトークンのチェックだけでなく、X-CSRF-TOKENもチェックする
    • htmlのmetaタグに含まれる
    • XSRF-TOKENクッキーにトークンが保存されるので、X-CSRF-TOKENの設定ができる
まさとまさと

コントローラ

  • シングルアクションコントローラ
    • アクションが複雑な場合に、そのアクション専用のコントローラーを作るとよい
    • __invoke()に処理を書く
  • コントローラのコンストラクタ内でミドルウェアを指定可能
  • ミドルウェアクラスを定義せずに、インラインで書くことも可能
public function __construct()
   {
       $this->middleware('auth');
       $this->middleware('log')->only('index');
       $this->middleware('subscribed')->except('store');
   }

$this->middleware(function (Request $request, Closure $next) {
   return $next($request);
});
  • リソースコントローラー
    • artisanでコントローラーを作成する際に、--resourceをつけることで、モデルへのCRUD処理をサクッと生成できる
    • Route::resource('photos', PhotoController::class);とするとリソースに対する必要なアクションをへのルートを定義してくれる
      • only, exceptでどのアクションへのルートを定義するかを指定できる
    • API用のリソースコントローラーも作成可能(HTMLを返すアクションを除外する)
    • ネストしたルーティングでもOK
    • デフォルトのルート名から変更したい場合はnames()に渡す配列で指定できる
    • リソースルートで生成されるルート以外にもルートを追加したい場合は、resourceの前に定義しておく
    • 単一のリソースであれば、singletonで作成する
  • コントローラーのコンストラクタに必要な依存をタイプヒントで指定しておくことで、自動的に依存解決してくれる
  • メソッドでも依存を指定できる
    • RequestとModelはよく指定しますね…
まさとまさと

HTTPリクエスト

  • Illuminate\Http\Requestはアプリケーションが処理しているHTTPリクエストの操作を提供
    • 入力・クッキー・ファイルを取得する手段
  • ルーティング・コントローラーでタイプヒントすることで、サービスコンテナによって依存注入してくれる
  • パス・URL・ホスト・メソッドの取得やチェックができる
  • header, hasHeader, bearerTokenを用いてヘッダーの情報の取得ができる
  • 入力値の取得
    • 全て取得する場合はall, collect
    • 単一の値であれば、input
    • クエリ文字列であれば、query
    • その他、JSONや論理値、日付を取得する際に便利なメソッドがある
  • 入力値のチェック
    • has, hasAny, whenHas, filled, anyFillled, whenFilledなど
    • 入力値が存在しているかのチェックだけでなく、存在している場合・していない場合に実行するクロージャを渡すこともできる
  • 入力に対して、情報を追加することも可能
    • merge, mergeIfMissing
  • cookieメソッドでクッキーの値を取得できる
    • 署名されており、クライアントによって書き換えられるとクッキーを無効とみなせる
  • 入力のトリミングと正規化
    • グローバルミドルウェアとして、TrimStringConvertEmptyStringsToNullが動いている
      • 受信文字列フィールドを自動的にトリミング・空の文字列フィールドをnullに変換する
    • 無効にする場合はKernelのプロパティから削除
    • 一部のリクエストに対して除外したい場合は、skipWhenを使用する
  • ファイルの取得・チェック
    • fileで取得
    • hasFileでファイルが存在するか
    • isValidでファイルのアップロードに問題がないか確認
    • 他にも色々ある→UploadedFileクラスを参照
  • ファイルの保存
    • store, storeAsを使用する
    • 保存するディレクトリや名前を決められる
  • プロキシの設定
    • ロードバランサとアプリケーションがHTTPで通信している場合、urlヘルパはHTTP~のURLを生成してしまう
      • TrustProxiesミドルウェアを使用して、プロキシを信頼することでHTTPSのリンクが生成される
      • プロキシのIPがわからない場合は*によってすべて信頼する
    • 信頼するホストの設定
      • Laravelはデフォルトでは受け取った全てのリクエストに応答する
      • App\Host\Middleware\TrustHostsで応答するホストを指定できる
まさとまさと

レスポンス

  • ルートやコントローラーで文字列や配列をreturnするとHTTPレスポンスにしてくれる
    • 配列はJSONになる
  • Responseインスタンスのメソッドでヘッダーやステータスコードをカスタマイズできる
  • Cache-Controlも簡単に指定できる
  • cookieメソッドでクッキーを添付できる
    • Cookieファサードでクッキーを添付することも可能→レスポンス送信前に添付される
    • グローバルcookieヘルパを使用すると、自分でアタッチする必要のあるcookieインスタンスを作成できる
  • withoutCookieCookie::expireでcookieの期限切れによる削除が可能
  • クッキーはデフォルトで暗号化されているが、ミドルウェアないで特定のクッキーを除外することが可能
  • リダイレクト
    • redirectRedirectResponseのインスタンスを返すことでリダイレクトさせる
    • 以前の場所にはbackで戻ることが可能だが、webミドルウェアグループを使用する
    • 名前付きルートのリダイレクトや、モデルのIDを持つURIの場合は、モデルを渡すとIDが取り出される
    • actionでコントローラーアクションにリダイレクトできる
    • awayで外部ドメインにもリダイレクト可能
    • フラッシュデータや入力内容をセッションに保存し、リダイレクトができる
  • ヘッダーやステータスコードに手を加えてviewを返すことも可能
  • JSON, Fileダウンロード, Fileレスポンスも可能
  • macroによって再利用可能なカスタムレスポンスを定義できる
まさとまさと

セッション

  • config/session.phpで設定できる
  • ドライバ
    • file
    • cookie
    • database
      • セッション用のテーブルを作成する php artisan session:tableで作成できる
    • memecached/redis
      • Redisの場合は、predisパッケージが必要
    • dynamodb
    • array(PHPの配列、永続化されない)
  • RequestインスタンスのメソッドでもPHPのsessionでもどちらからもセッションは利用可能
    • どちらも違いはないらしい…?
  • 取得
  • 存在判定
  • 追加(pullだと、取得後削除してくれる)
  • flash で次のリクエストまでデータを保持できる。
    • 複数のリクエスト間保持したい場合は、reflashを使う
    • nowだと今回のリクエストのみ
  • regenerate, invalidateでセッションIDを再生成できる
  • blockにより同じセッションを扱うリクエストを制限できる
  • セッションドライバを自作できる
まさとまさと

ログ

  • チャンネルに基づいている
  • config/logging.phpで色々設定できる
  • チャンネルドライバは複数ある
    • daily, singleはオプションがある
    • 非推奨の警告を出すことも可能
  • ログのレベルには8種類ある →RFCで定義されている
  • logContext, shareContextで後続のログ・複数のチャンネルにコンテキストを共有できる
  • ログのメソッド呼び出し時に、チャンネルを指定したり、作成したりできる
  • Monolog関連のカスタマイズもできる
  • Pailを使うとログを見るのに便利
まさとまさと

エラー処理

  • App\Exceptions\Handlerクラスが、アプリケーションから投げられた全ての例外をログに記録、ユーザーへレンダリングする亜書
  • contextメソッドにより、定義したデータを全ての例外ログメッセージに含められる
  • reportを使った場合に、一つの例外インスタンスが複数報告されないように、withoutDuplicatesを使用可能
  • 例外ごとにログレベルを指定することができる
  • 無視する例外のレポートを指定可能
  • 例外を受け取ったら任意のレスポンスにすることも可能
  • 例外に直接report, renderを記述できる
  • 報告・ログに記録する例外を時間やランダムで絞り込むことができる
  • abortで任意の場所でHTTPエラーレスポンスを返せる
  • 対応するステータスコードのビューを作成可能
まさとまさと

認証

  • ガードとプロバイダで構成されている
    • ガード:リクエストごとにユーザーを認証する方法
    • プロバイダ:永続ストレージからユーザーを取得する方法
  • Webブラウザ:認証したユーザー情報をセッションに保存、クッキーにセッションIDが保存され、以降のリクエストの際に紐づけられる
  • リモートサービス:リクエストごとにAPIトークンを送信、APIはテーブルに有効なトークンの一覧を保持し、受信したトークンと一致するかを確認して認証する
  • Laravelの組み込み認証
    • セッション:Fortify, Breeze, Jetstream
    • APIトークン:Passport, Sanctum
  • basic認証が用意されている
  • 他のデバイスのセッションだけを無効化させられる
このスクラップは2024/03/19にクローズされました