この記事では主に、一定の参考価値のあるLaravel Requestのコア解釈を紹介します。今から皆さんに共有します。必要な友人は参考にしてください。
多くのフレームワークは、クライアントからのリクエストは、アプリケーションで簡単に使用できるようにクラスに抽象化されます。Laravel も例外ではありません。 Illuminate\Http\Request
クラスは、Laravel フレームワークのクライアント リクエストの抽象化であり、Symfony
フレームワークによって提供される Request コンポーネントに基づいて構築されます。今日の記事では、Laravel が 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
を介した
クラス <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's bug #66606, the php'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 ('cli-server' === PHP_SAPI) { if (array_key_exists('HTTP_CONTENT_LENGTH', $_SERVER)) { $server['CONTENT_LENGTH'] = $_SERVER['HTTP_CONTENT_LENGTH']; } if (array_key_exists('HTTP_CONTENT_TYPE', $_SERVER)) { $server['CONTENT_TYPE'] = $_SERVER['HTTP_CONTENT_TYPE']; } } $request = self::createRequestFromFactory($_GET, $_POST, array(), $_COOKIE, $_FILES, $server); if (0 === strpos($request->headers->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded') && in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), array('PUT', 'DELETE', 'PATCH')) ) { parse_str($request->getContent(), $data); $request->request = new ParameterBag($data); } return $request; } }
php -S localhost:8000 -t htdocsしかし、組み込み Web サーバーには 2 つのリクエスト ヘッダー-S <addr>:<port> Run with built-in web server. -t <docroot> Specify document root <docroot> for built-in web server.ログイン後にコピー
CONTENT_LENGTH と
CONTENT_TYPE を保存するバグがあります。
HTTP_CONTENT_LENGTH と
HTTP_CONTENT_TYPE では、組み込みサーバーと実サーバーのリクエスト ヘッダー フィールドを統一するために、ここで特別な処理が行われます。
$_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->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->request = new ParameterBag($request);
$this->query = new ParameterBag($query);
$this->attributes = new ParameterBag($attributes);
$this->cookies = new ParameterBag($cookies);
$this->files = new FileBag($files);
$this->server = new ServerBag($server);
$this->headers = new HeaderBag($this->server->getHeaders());
$this->content = $content;
$this->languages = null;
$this->charsets = null;
$this->encodings = null;
$this->acceptableContentTypes = null;
$this->pathInfo = null;
$this->requestUri = null;
$this->baseUrl = null;
$this->basePath = null;
$this->method = null;
$this->format = null;
}
}</pre><div class="contentsignin">ログイン後にコピー</div></div>
Symfony Request クラスには、上で説明したものに加えて多くの属性があることがわかります。これらの属性は一緒になって HTTP リクエストの完全な抽象化を形成します。インスタンス属性を通じて簡単にアクセスできます
、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('_format') && $this->get('_format')) { $dup->attributes->set('_format', $this->get('_format')); } if (!$dup->getRequestFormat(null)) { $dup->setRequestFormat($this->getRequestFormat(null)); } return $dup; }
Request オブジェクトが作成されたら、それを Laravel アプリケーションに簡単に適用できます。 Request オブジェクトを使用すると、必要な機能が実現されているかどうかがわからない場合、
Illuminate\Http\Request のソース コード ファイルに直接アクセスして確認するのが非常に簡単です。このソース コード ファイルでは、次のようにリストされます。 概要 この記事は主に Laravel の Request オブジェクトを整理しています。主に、Laravel の Request が現在提供しているどの機能を使用すれば、Request を実装するためのビジネス コードの車輪の再発明を避けることができるかを調べる方法を皆さんに知ってもらいたいと考えています。 .メソッドはすでに提供されています。 上記がこの記事の全内容です。皆様の学習に少しでもお役に立てれば幸いです。その他の関連コンテンツについては、PHP 中国語 Web サイトをご覧ください。 関連する推奨事項: 以上がリクエストのLaravelコア解釈の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。/**
* Get the full URL for the request.
* 获取请求的URL(包含host, 不包括query string)
*
* @return string
*/
public function fullUrl()
{
$query = $this->getQueryString();
$question = $this->getBaseUrl().$this->getPathInfo() == '/' ? '/?' : '?';
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() == '/' ? '/?' : '?';
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 オブジェクトに変換され、リクエストを開始したクライアントに返されます。