LoginSignup
132
123

More than 3 years have passed since last update.

Requestの各メソッド(query(), get(), all()...)の使い分け

Last updated at Posted at 2018-05-31

自分のレベルが低いうちは

  • get()で大体取れる
  • プロパティアクセスでも大体取れる
  • get()input()との違いを聞かれてもわからない
  • only()except()で欲しいものだけ取れるすごい
  • all()で全部取れるすごい

ぐらいの認識だったが、ちゃんと使い分けが出来そうだったのでメモ。

マサカリ歓迎。

結論

  • クエリストリングだけ取得したいならquery()
  • リクエストボディのみを取得したい場合の関数は存在しない($requestプロパティにアクセスすれば可能)
  • リクエストボディ+クエリストリング(クエリストリング優先)はget()
  • リクエストボディ+クエリストリング(リクエストボディ優先)はinput()
  • all()input()+ファイル
  • only()except()all()を利用している
  • プロパティアクセスはall()+ルートパラメータを利用している

前提

symfony\http-foundation\Requestに3つのプロパティがあり、これらがリクエストのデータを扱っている

symfony\http-foundation\Request.php
    /**
     * Custom parameters.
     *
     * @var \Symfony\Component\HttpFoundation\ParameterBag
     */
    public $attributes;

    /**
     * Request body parameters ($_POST).
     *
     * @var \Symfony\Component\HttpFoundation\ParameterBag
     */
    public $request;

    /**
     * Query string parameters ($_GET).
     *
     * @var \Symfony\Component\HttpFoundation\ParameterBag
     */
    public $query;

$attributes

追加データを格納できるプロパティ。いろんなポイントからアクセスする必要がある情報はここに入れてね!
みたいなことが下記URLに書いてある(と思う)が、どんな場合に有用なのか、思いつかなかった。
自分で何か入れない限り、基本的には空(のはず)。

Thanks to the public attributes property, you can store additional data in the request, which is also an instance of ParameterBag. This is mostly used to attach information that belongs to the Request and that needs to be accessed from many different points in your application.

$request

$_POST
http://php.net/manual/ja/reserved.variables.post.php

$query

$_GET
http://php.net/manual/ja/reserved.variables.get.php

(本当に$_POST$_GETと全く同じかどうかは未検証だが、本題とはズレるのでここでは扱わない。)

各メソッド

get()

symfony/http-foundation/Request.php
    /**
     * Gets a "parameter" value from any bag.
     *
     * This method is mainly useful for libraries that want to provide some flexibility. If you don't need the
     * flexibility in controllers, it is better to explicitly get request parameters from the appropriate
     * public property instead (attributes, query, request).
     *
     * Order of precedence: PATH (routing placeholders or custom attributes), GET, BODY
     *
     * @param string $key     The key
     * @param mixed  $default The default value if the parameter key does not exist
     *
     * @return mixed
     */
    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 -> $request -> $query
の順番で要素を探しに行く。

メモ:リクエストボディよりもクエリストリングが優先される。

query()

laravel\framework\src\Illuminate\Http\Concerns\InteractsWithInput.php
    /**
     * Retrieve a query string item from the request.
     *
     * @param  string  $key
     * @param  string|array|null  $default
     * @return string|array
     */
    public function query($key = null, $default = null)
    {
        return $this->retrieveItem('query', $key, $default);
    }


    /**
     * Retrieve a parameter item from a given source.
     *
     * @param  string  $source
     * @param  string  $key
     * @param  string|array|null  $default
     * @return string|array
     */
    protected function retrieveItem($source, $key, $default)
    {
        if (is_null($key)) {
            return $this->$source->all();
        }

        return $this->$source->get($key, $default);
    }

$queryだけを見に行く

メモ:クエリストリングのみを扱う。

input()

laravel\framework\src\Illuminate\Http\Concerns\InteractsWithInput.php
    /**
     * Retrieve an input item from the request.
     *
     * @param  string  $key
     * @param  string|array|null  $default
     * @return string|array
     */
    public function input($key = null, $default = null)
    {
        return data_get(
            $this->getInputSource()->all() + $this->query->all(), $key, $default
        );
    }
laravel\framework\src\Illuminate\Http\Request.php
    /**
     * Get the input source for the request.
     *
     * @return \Symfony\Component\HttpFoundation\ParameterBag
     */
    protected function getInputSource()
    {
        if ($this->isJson()) {
            return $this->json();
        }

        return $this->getRealMethod() == 'GET' ? $this->query : $this->request;
    }

(JSONの場合分けに関しては、まだ読んでいないので本記事では扱いません)

  1. メソッドがGETであれば$queryを、そうでなければ$requestを取得する
  2. 上記に$queryを加えたものからデータを取得する(演算子のため先勝ち)

メモ:メソッドによって扱うパラメータが変わるが、クエリストリングは必ず扱う
メモ:キーが重複した場合はリクエストボディが優先

all()

laravel\framework\src\Illuminate\Http\Concerns\InteractsWithInput.php
    /**
     * Get all of the input and files for the request.
     *
     * @param  array|mixed  $keys
     * @return array
     */
    public function all($keys = null)
    {
        $input = array_replace_recursive($this->input(), $this->allFiles());

        if (! $keys) {
            return $input;
        }

        $results = [];

        foreach (is_array($keys) ? $keys : func_get_args() as $key) {
            Arr::set($results, $key, Arr::get($input, $key));
        }

        return $results;
    }

上述のinput()にファイルを加えたもの
(ファイルに関しては本記事では深くは扱わない)

メモ:ファイルを加えたinput()

only(), except()

laravel\framework\src\Illuminate\Http\Concerns\InteractsWithInput.php
    /**
     * Get a subset containing the provided keys with values from the input data.
     *
     * @param  array|mixed  $keys
     * @return array
     */
    public function only($keys)
    {
        $results = [];

        $input = $this->all();

        $placeholder = new stdClass;

        foreach (is_array($keys) ? $keys : func_get_args() as $key) {
            $value = data_get($input, $key, $placeholder);

            if ($value !== $placeholder) {
                Arr::set($results, $key, $value);
            }
        }

        return $results;
    }
laravel\framework\src\Illuminate\Http\Concerns\InteractsWithInput.php
    /**
     * Get all of the input except for a specified array of items.
     *
     * @param  array|mixed  $keys
     * @return array
     */
    public function except($keys)
    {
        $keys = is_array($keys) ? $keys : func_get_args();

        $results = $this->all();

        Arr::forget($results, $keys);

        return $results;
    }

どちらもall()を利用している

プロパティアクセス

laravel/framework/src/Illuminate/Http/Request.php
    /**
     * Get an input element from the request.
     *
     * @param  string  $key
     * @return mixed
     */
    public function __get($key)
    {
        if (array_key_exists($key, $this->all())) {
            return data_get($this->all(), $key);
        }

        return $this->route($key);
    }

all()になければルートパラメータを探しに行く。

マジックメソッドなので、オブジェクト内にアクセス可能プロパティがあるときはオブジェクトのプロパティが優先される。

メモ:ルートパラメータも取得できる

メモ:オブジェクト内のアクセス可能プロパティ -> all() -> ルートパラメータの順に優先される

おまけ

リクエストボディのみを取得したい

$requestプロパティにアクセスすることで可能。

$request->request->get('hoge');
$request->request->all();
132
123
1

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
132
123