Laravel リクエストを自在に操る方法

Webアプリケーションはユーザーからのリクエストに基づいて、レスポンスを返すと言う役割を担っています。

そのため、リクエストをどのように処理をするのかを理解することは、
Webアプリケーションの構築をしていく上で必要不可欠な知識となります。

そこでで今回はhttpリクエストをどのようにハンドリングしていくかについてお伝えしていきます。

HTTPリクエストを取得するためには

まず初めにどのようにhttpリクエストを習得していくのかということについてお伝えしていきます。

Laravelではpublic/index.php 内の下記部分において、 httpカーネルを通して、handleメソッド内でリクエストを扱っています。

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

このリクエストをコントローラーで参照するためには、下記2つの方法があります。

1,Input,Request ファサードを利用する
2,Request クラスをメソッドインジェクションを介して使用する

Input,Requestファサードを利用する

Input,Requestファサードを利用することで、リクエストを習得することができます。

まずは、Requestファサードを見てみます

RequestファサードはIlluminateHttpRequestから来ています。

まずはRequestファサードで使うことができるメソッドを見ていきましょう。

get()
input()関連ファイルを含ず、リクエストを返す
all()関連ファイルを含めて、リクエストを全て返します。
only()指定したkeyのみをクエストを返します。
except()指定したkeyを除いてクエストを返します。

Url、パラメータ関連の取得

path()リクエストURIの取得
is() リクエストのURIが指定されたパターンに合致するか確認
url() 完全なURLを取得(クエリ文字列なし)
fullUrl()完全なURLを取得(クエリ文字列付き)
method()リクエストメソッドの取得
isMethod()リクエストメソッドの取得
query() パラメータの取得
例:http://localhost/user?name=yamada の 20の部分を取り出す

続いてLaravelを使う上でよく利用することになるquery,input,getの区別をその構造から見ていきましょう。

queryメソッド

    public function query($key = null, $default = null)
    {
        return $this->retrieveItem('query', $key, $default);
    }	

RequestからトレイトでConcernsInteractsWithInput.phpに記載されています。
http://localhost:8000/1?id=“ささみ”というurlの場合,id => ささみの連想配列を返す。

複数ある場合、はkeyを指定することで、その値を取得することができます。クエリ取得時のみ使うことに注意してください。

Inputメソッド

文字列のパラメータの取得($GET)と同じ

public function input($key = null, $default = null)
    {
        return data_get(
            $this->getInputSource()->all() + $this->query->all(), $key, $default
        );
    }

こちらもトレイトでIlluminateHttpConcernsInteractsWithInput.phpから使っています。getInputSourceはIlluminateHttpRequest.phpにあります。

protected function getInputSource()
    {
        if ($this->isJson()) {
            return $this->json();
        }➡︎①

        return in_array($this->getRealMethod(), ['GET', 'HEAD']) ? $this->query : ➡︎② 
	$this->request; ➡︎③
    }

順番に見てみましょう。まず最初にJsonであれば、jsonを返す処理が行われています。(①)
続いて、②getメソッドがどうかの判定をして、そうであればqueryを返しています。
➡︎③そうでない場合は、requestを返すという処理になっています。

先ほどのid=>ささみというクエリは、inputでも取得することができます。

getメソッド

    public function get($key, $default = null)
    {
        return parent::get($key, $default);
    }

本体は、Symphony HttpFoundationにあるので、こちらも見てみましょう

    public function get($key, $default = null)
    {
        if ($this !== $result = $this->attributes->get($key, $this)) {
            return $result;
        }

        if ($this !== $result = $this->query->get($key, $this)) {
            return $result;
        }

        if ($this !== $result = $this->request->get($key, $this)) {
            return $result;
        }

        return $default;
    }
attributesカスタムパラメーター
query文字列のパラメータの取得($GET)と同じ
requestPostで送られるフォームのデータ($POST).と同じ

基本的には、これまでのinputとqueryを合わせたような処理をしてくれる。

ただしquery,inputは何も$keyを指定しなくても、配列を返してくれましたが、
getの場合は、取得したい$keyの指定が必要になるので注意してください。

attributes ➡︎query ➡︎requestの順番で処理をしていきます。


続いて、Inputファサードを見ていきましょう。といっても基本的にはInputファサードは同じです。下記のようにInputファサードでは、Requestファサードと同じrequestとしています。

protected static function getFacadeAccessor()
    {
        return 'request';
    }
}

Inputファサードの場合は、下記の処理がファサードに記載されているため、$keyの指定なしでgetメソッドが使用できる以外は、requestと同じと考えて良いでしょう

    public static function get($key = null, $default = null)
    {
        return static::$app['request']->input($key, $default);
    }

ファイルの取得

アップロードしたファイルを取得するための方法をここでは見ていきます。
方法は下記二つがあります。

1,上述したIlluminateHttpRequestのfileメソッド

2,自分でアップロード時に設定したフォームのプロパティ

$file = $request->file(‘picture’);
$file = $request-> picture;
よく使う便利なメッソドの紹介

ファイル取得時に使う便利なメソッドを照会しておきます。

hasfile()リクエストの中にfileが存在しているかどうかチェック
isvalid()存在確認に加えてアップロードできているかどうかをisvalidメソッドで確認
getMaxFilesize()php.ini.に設定されたアップロードファイルの限界サイズを確認できます。
getClientSize()ファイルサイズの取得。
getClientMimeType()ファイルのmimeタイプを取得
getClientOriginalName()ファイル名を取得
getErrorMessage()アップロード時のエラーメッセージを取得。

アップロードファイルを外部ストレージに保存

Laravelにはアップロードされたファイルをs3に保存したりローカルに保存したりすることができます。
Amazon s3にアップロードすることが一般的になると思いますが、具体的な方法は別記事にてお伝えします。

Request クラスをメソッドインジェクションを介して使用する

続いて、Requestクラスをメソッドインジェクションで使う場合を考えてみましょう。
とは言ってもこちらの処理は簡単です。

下記のようにRequest $requestの形でタイプヒンティングを行うことで、requestクラスを処理することができます。IlluminateHttpRequestのRequestを直接入れ込むことができます。

public function index(Request $request)
    {
        dd($request->all());
    }

カスタムリクエストクラス(フォームリクエスト)の作成

これまでは、IlluminateHttpRequestを使っていましたが、このクラスを自作してそこで、リクエストをハンドリングすることができます。

基本的にはここでは、バリデーションのハンドリングを行うことが主になります。

バリデーションが複雑になったりしてコントローラーの可読性を高めたり、

独自のメッセージを入れたい場合には使うことになるでしょう。

*バリデーションの処理については、長くなるので、また別の記事でお伝えします。

それ以外の特殊なものとしては、認証されているユーザーのみにリクエストを許可するというミドルウェアのような役割もあります。

下記に例を出します。

public function authorize()
{
    $commentId = $this->route('comment'); ➡︎1
 
    return Comment::where('id', $commentId)
                  ->where('user_id', Auth::id())->exists(); ➡︎2
}

1において、routeにて、自身がかきのようにrouterで定義したパラメーターを持ってきます。

Route::post(‘comment/comment’);

commnentIdを持ってくることができ、そのidがあるかどうかを判定しています。

ここでfalseが返ると403ステータスコードが返ってきて、コントローラは実行されません。

ここが意外と重要なのですが、上記のような認証処理をしようせずに単に値を返したい場合は、シンプルにtrueを返しておくことで、判定をしないですることができます。

まとめ

Laravelのリクエストハンドリングは、基礎中の基礎でwebアプリケーションapi作成のためには必要不可欠の知識です。使いこなせるようにしてくださいね。

コメントを残す