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