Help us understand the problem. What is going on with this article?

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

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

  • 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に書いてある(と思う)が、どんな場合に有用なのか、思いつかなかった。
自分で何か入れない限り、基本的には空(のはず)。

http://symfony.com/doc/current/components/http_foundation.html#component-foundation-attributes

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();
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away