リクエストのLaravelコア解釈

不言
リリース: 2023-04-02 17:10:01
オリジナル
4051 人が閲覧しました

この記事では主に、一定の参考価値のあるLaravel Requestのコア解釈を紹介します。今から皆さんに共有します。必要な友人は参考にしてください。

Request

多くのフレームワークは、クライアントからのリクエストは、アプリケーションで簡単に使用できるようにクラスに抽象化されます。Laravel も例外ではありません。 Illuminate\Http\Request クラスは、Laravel フレームワークのクライアント リクエストの抽象化であり、Symfony フレームワークによって提供される Request コンポーネントに基づいて構築されます。今日の記事では、Laravel が Request オブジェクトを作成する方法について簡単に説明します。Request オブジェクトがアプリケーションに提供する機能については、あまり詳しく説明しません。作成プロセスの説明が終わったら、どこに行くべきかがわかるでしょう。ソース コードです。Request オブジェクトによって提供されるメソッドを探します。インターネット上の一部のチートシートには、Request によって提供されるメソッドがリストされていますが、それらは完全ではなく、説明されていないものもあります。したがって、興味がある場合は、これをお勧めします。 Request が開発中に希望する機能を実現しているかどうかについて Request のソースコードにアクセスして、対応するメソッドがあるかどうかを確認し、各メソッドの実行結果をメソッドのコメントに明示します。本題に入りましょう。

Request オブジェクトの作成

Laravel アプリケーションの index.php ファイルで、Laravel アプリケーションが正式に開始される前に Request オブジェクトが作成されたことがわかります。 OK:

//public/index.php
$app = require_once __DIR__.'/../bootstrap/app.php';

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    //创建request对象
    $request = Illuminate\Http\Request::capture()
);
ログイン後にコピー

クライアントの HTTP リクエストは、Illuminate\Http\Request を介した

Illuminate\Http\Request

クラス <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">class Request extends SymfonyRequest implements Arrayable, ArrayAccess { //新建Request实例 public static function capture() { static::enableHttpMethodParameterOverride(); return static::createFromBase(SymfonyRequest::createFromGlobals()); } }</pre><div class="contentsignin">ログイン後にコピー</div></div> のオブジェクトです。ソースコードから、Symfony Request クラスから継承していることがわかります。そのため、Illuminate\Http\Request クラスに実装された多くの関数は、Symfony Reques# によって提供されています。 ## 関数ベースの実装。上記のコードから、capture メソッドは、新しい Request オブジェクトを作成するときに Symfony Request クラスのインスタンスにも依存していることがわかります。

namespace Symfony\Component\HttpFoundation;
class Request
{
    /**
     * 根据PHP提供的超级全局数组来创建Smyfony Request实例
     *
     * @return static
     */
    public static function createFromGlobals()
    {
        // With the php&#39;s bug #66606, the php&#39;s built-in web server
        // stores the Content-Type and Content-Length header values in
        // HTTP_CONTENT_TYPE and HTTP_CONTENT_LENGTH fields.
        $server = $_SERVER;
        if (&#39;cli-server&#39; === PHP_SAPI) {
            if (array_key_exists(&#39;HTTP_CONTENT_LENGTH&#39;, $_SERVER)) {
                $server[&#39;CONTENT_LENGTH&#39;] = $_SERVER[&#39;HTTP_CONTENT_LENGTH&#39;];
            }
            if (array_key_exists(&#39;HTTP_CONTENT_TYPE&#39;, $_SERVER)) {
                $server[&#39;CONTENT_TYPE&#39;] = $_SERVER[&#39;HTTP_CONTENT_TYPE&#39;];
            }
        }

        $request = self::createRequestFromFactory($_GET, $_POST, array(), $_COOKIE, $_FILES, $server);

        if (0 === strpos($request->headers->get(&#39;CONTENT_TYPE&#39;), &#39;application/x-www-form-urlencoded&#39;)
            && in_array(strtoupper($request->server->get(&#39;REQUEST_METHOD&#39;, &#39;GET&#39;)), array(&#39;PUT&#39;, &#39;DELETE&#39;, &#39;PATCH&#39;))
        ) {
            parse_str($request->getContent(), $data);
            $request->request = new ParameterBag($data);
        }

        return $request;
    }
    
}
ログイン後にコピー

上記のコードには追加の説明が必要な点が 1 つあります。PHP5.4 以降、PHP の組み込み Web サーバーは、コマンド ライン インタープリターを介して起動できます。例:

php -S localhost:8000 -t htdocs

-S <addr>:<port> Run with built-in web server.
-t <docroot>     Specify document root <docroot> for built-in web server.
ログイン後にコピー

しかし、組み込み Web サーバーには 2 つのリクエスト ヘッダー

CONTENT_LENGTHCONTENT_TYPE を保存するバグがあります。 HTTP_CONTENT_LENGTHHTTP_CONTENT_TYPE では、組み込みサーバーと実サーバーのリクエスト ヘッダー フィールドを統一するために、ここで特別な処理が行われます。

Symfony Request インスタンスは、PHP のスーパー グローバル配列を通じて作成されます。これらのスーパー グローバル配列には、

$_GET$_POST$ _COOKIE$_FILES$_SERVER は、PHP の HTTP リクエストに関連するすべてのスーパー グローバル配列をカバーします。Symfony Request インスタンスを作成するとき、Symfony パッケージはこれらのグローバル配列に基づいて作成されます。 ##ParamterBag ServerBag FileBag HeaderBag インスタンスこれらのバッグは、さまざまな HTTP コンポーネント用に Symfony が提供する API にアクセスおよび設定します。これらに興味のある読者Symfony が提供する ParamterBag の例では、ソース コード自体をチェックアウトできます。ここでは詳細は説明しません。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">class Request { /** * @param array $query The GET parameters * @param array $request The POST parameters * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...) * @param array $cookies The COOKIE parameters * @param array $files The FILES parameters * @param array $server The SERVER parameters * @param string|resource|null $content The raw body data */ public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) { $this-&gt;initialize($query, $request, $attributes, $cookies, $files, $server, $content); } public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) { $this-&gt;request = new ParameterBag($request); $this-&gt;query = new ParameterBag($query); $this-&gt;attributes = new ParameterBag($attributes); $this-&gt;cookies = new ParameterBag($cookies); $this-&gt;files = new FileBag($files); $this-&gt;server = new ServerBag($server); $this-&gt;headers = new HeaderBag($this-&gt;server-&gt;getHeaders()); $this-&gt;content = $content; $this-&gt;languages = null; $this-&gt;charsets = null; $this-&gt;encodings = null; $this-&gt;acceptableContentTypes = null; $this-&gt;pathInfo = null; $this-&gt;requestUri = null; $this-&gt;baseUrl = null; $this-&gt;basePath = null; $this-&gt;method = null; $this-&gt;format = null; } }</pre><div class="contentsignin">ログイン後にコピー</div></div>Symfony Request クラスには、上で説明したものに加えて多くの属性があることがわかります。これらの属性は一緒になって HTTP リクエストの完全な抽象化を形成します。インスタンス属性を通じて簡単にアクセスできます

Method

Charset、およびこれらの HTTP リクエストのその他の属性。 Symfony Request インスタンスを取得した後、Laravel はインスタンスのクローンを作成し、そのプロパティの一部をリセットします:

namespace Illuminate\Http;
class Request extends ....
{
    //在Symfony request instance的基础上创建Request实例
    public static function createFromBase(SymfonyRequest $request)
    {
        if ($request instanceof static) {
            return $request;
        }

        $content = $request->content;

        $request = (new static)->duplicate(
            $request->query->all(), $request->request->all(), $request->attributes->all(),
            $request->cookies->all(), $request->files->all(), $request->server->all()
        );

        $request->content = $content;

        $request->request = $request->getInputSource();

        return $request;
    }
    
    public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null)
    {
        return parent::duplicate($query, $request, $attributes, $cookies, $this->filterFiles($files), $server);
    }
}
    //Symfony Request中的 duplicate方法
    public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null)
    {
        $dup = clone $this;
        if (null !== $query) {
            $dup->query = new ParameterBag($query);
        }
        if (null !== $request) {
            $dup->request = new ParameterBag($request);
        }
        if (null !== $attributes) {
            $dup->attributes = new ParameterBag($attributes);
        }
        if (null !== $cookies) {
            $dup->cookies = new ParameterBag($cookies);
        }
        if (null !== $files) {
            $dup->files = new FileBag($files);
        }
        if (null !== $server) {
            $dup->server = new ServerBag($server);
            $dup->headers = new HeaderBag($dup->server->getHeaders());
        }
        $dup->languages = null;
        $dup->charsets = null;
        $dup->encodings = null;
        $dup->acceptableContentTypes = null;
        $dup->pathInfo = null;
        $dup->requestUri = null;
        $dup->baseUrl = null;
        $dup->basePath = null;
        $dup->method = null;
        $dup->format = null;

        if (!$dup->get(&#39;_format&#39;) && $this->get(&#39;_format&#39;)) {
            $dup->attributes->set(&#39;_format&#39;, $this->get(&#39;_format&#39;));
        }

        if (!$dup->getRequestFormat(null)) {
            $dup->setRequestFormat($this->getRequestFormat(null));
        }

        return $dup;
    }
ログイン後にコピー

Request オブジェクトが作成されたら、それを Laravel アプリケーションに簡単に適用できます。 Request オブジェクトを使用すると、必要な機能が実現されているかどうかがわからない場合、

Illuminate\Http\Request

のソース コード ファイルに直接アクセスして確認するのが非常に簡単です。このソース コード ファイルでは、次のようにリストされます。

/**
 * Get the full URL for the request.
 * 获取请求的URL(包含host, 不包括query string)
 *
 * @return string
 */
public function fullUrl()
{
    $query = $this->getQueryString();

    $question = $this->getBaseUrl().$this->getPathInfo() == &#39;/&#39; ? &#39;/?&#39; : &#39;?&#39;;

    return $query ? $this->url().$question.$query : $this->url();
}

/**
 * Get the full URL for the request with the added query string parameters.
 * 获取包括了query string 的完整URL
 *
 * @param  array  $query
 * @return string
 */
public function fullUrlWithQuery(array $query)
{
    $question = $this->getBaseUrl().$this->getPathInfo() == &#39;/&#39; ? &#39;/?&#39; : &#39;?&#39;;

    return count($this->query()) > 0
        ? $this->url().$question.http_build_query(array_merge($this->query(), $query))
        : $this->fullUrl().$question.http_build_query($query);
}
ログイン後にコピー
リクエストが通過するステーション

リクエスト オブジェクトを作成した後、Laravel の Http カーネルは実行を継続します。サービス プロバイダーをロードして、リクエストをガイドします。 Laravelアプリケーションは、アプリケーションを起動し、リクエストを基本ミドルウェアを経由させ、ルーターマッチングによりリクエストに対応するルートを見つけ、一致したルートを実行し、リクエストはルートを通ってミドルウェアに到達し、コントローラーメソッドに到達します。

概要

リクエストが最終的に対応するコントローラー メソッドに到達すると、そのミッションは基本的に完了します。コントローラー メソッドでは、入力パラメーターがリクエストから取得され、アプリケーションの特定の側面が取得されます。ビジネス ロジックが結果を取得すると、結果は Response オブジェクトに変換され、リクエストを開始したクライアントに返されます。

この記事は主に Laravel の Request オブジェクトを整理しています。主に、Laravel の Request が現在提供しているどの機能を使用すれば、Request を実装するためのビジネス コードの車輪の再発明を避けることができるかを調べる方法を皆さんに知ってもらいたいと考えています。 .メソッドはすでに提供されています。

上記がこの記事の全内容です。皆様の学習に少しでもお役に立てれば幸いです。その他の関連コンテンツについては、PHP 中国語 Web サイトをご覧ください。

関連する推奨事項:

Laravel コア解釈ファサード

以上がリクエストのLaravelコア解釈の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!