namespace Illuminate\Http;
use Closure;
use ArrayAccess; // "支持數組和對象互相調用語法兼容接口"
use RuntimeException;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Support\Traits\Macroable; // "引入這個特質方便拓展類"
use Illuminate\Contracts\Support\Arrayable; // "須要類支持toArray()方法的契約"
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
// "laravel的請求類繼承了Symfony的的請求對象,同時須要支持toArray()契約和數組對象互相調用語法支持接口"
class Request extends SymfonyRequest implements Arrayable, ArrayAccess
{
use Concerns\InteractsWithContentTypes,
Concerns\InteractsWithFlashData,
Concerns\InteractsWithInput,
Macroable;
}
複製代碼
• 獲取請求對象
public static function capture()
{
// "這行指啓動方法重載,可以在前端經過 {{method_field('PUT')}} 僞造一個 PUT 或者 DELETE 請求。"
static::enableHttpMethodParameterOverride();
// "這行就是laravel怎麼捕獲整個請求中數據的關鍵,咱們來展開分解。"
return static::createFromBase(SymfonyRequest::createFromGlobals());
}
• 先看看如何生成一個SymfonyRequest請求對象的
public static function createFromGlobals()
{
// 經過傳入這些參數獲取SymfonyRequest的實例化對象
$request = self::createRequestFromFactory($_GET, $_POST, [], $_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')), ['PUT', 'DELETE', 'PATCH'])
) {
// "解析數據,若是是PUT,DELETE,PATCH這集中方法以及頭部是x-www-form-urlencoded則須要根據 數據類型是二進制,資源,流等來進行讀取而且賦值到數組$data"
parse_str($request->getContent(), $data);
// "new一個ParameterBag實例傳給$request對象的request屬性"
$request->request = new ParameterBag($data);
}
return $request;
}
// "上面的self::createRequestFromFactory($_GET, $_POST, [], $_COOKIE, $_FILES, $_SERVER)是調用SymfonyRequest初始化方法,只不過是將PHP超全局數組賦值給對象的對應成員。"
public function initialize(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null)
{
$this->request = new ParameterBag($request); // $_POST
$this->query = new ParameterBag($query); // $_GET
$this->attributes = new ParameterBag($attributes); // []
$this->cookies = new ParameterBag($cookies); // $_COOKIE
$this->files = new FileBag($files); // $_FILES
$this->server = new ServerBag($server); // $_SERVER
$this->headers = new HeaderBag($this->server->getHeaders())
$this->content = $content; // null
$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;
}
• 最後看如何根據SymfonyRequest請求實例來生成laravel的Request實例
public static function createFromBase(SymfonyRequest $request)
{
// "若是傳入的$request是Illuminate\Http\Request對象則直接返回。"
if ($request instanceof static) {
return $request;
}
// "讀取request中的內容"
$content = $request->content;
// "克隆一個新的對象將SymfonyRequest中的參數覆蓋其中的部分參數。"
$request = (new static)->duplicate(
$request->query->all(), $request->request->all(), $request->attributes->all(),
$request->cookies->all(), $request->files->all(), $request->server->all()
);
// "從新賦值給Illuminate\Http\Request對象。"
$request->content = $content;
// "獲取請求中的數據"
$request->request = $request->getInputSource();
// "返回Illuminate\Http\Request對象"
return $request;
}
複製代碼
laravel中的請求是在SymfonyRequest的基礎進行繼承,前端
同時增長了本身的一些方法進去。laravel
最終在框架中直接使用的是Illuminate\Http\Request對象。數組
固然請求類裏面還有不少其餘附帶的方法,bash
可是目前只分析在框架啓動過程當中請求對象cookie
是如何發揮做用的。app