【Laravel-海贼王系列】第五章,Request 类解析

深入剖析Laravel框架中请求类的工作原理,包括如何捕捉HTTP请求、生成SymfonyRequest对象及转换为Laravel的Request实例。

分解laravel的请求类,看看如何解析Http请求。

头部声明
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;

class Request extends SymfonyRequest implements Arrayable, ArrayAccess
{
    use Concerns\InteractsWithContentTypes,
        Concerns\InteractsWithFlashData,
        Concerns\InteractsWithInput,
        Macroable;
} // laravel的请求类继承了Symfony的的请求对象,同时需要支持toArray()契约和数组对象互相调用语法支持接口

复制代码
核心方法
• 获取请求对象

public static function capture() // 这是静态的
{
    static::enableHttpMethodParameterOverride();这行指启动方法重载,能够在前端通过 {{method_field('PUT')}} 伪造一个 PUT 或者 DELETE 请求。

    return static::createFromBase(SymfonyRequest::createFromGlobals());// 这行就是laravel怎么捕获整个请求中数据的关键,我们来展开分解。
}

• 先看看如何生成一个SymfonyRequest请求对象的

public static function createFromGlobals() 
    {
        $request = self::createRequestFromFactory($_GET, $_POST, [], $_COOKIE, $_FILES, $_SERVER); 通过传入这些参数获取SymfonyRequest的实例化对象

        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);
            $request->request = new ParameterBag($data); // new一个ParameterBag实例传给$request对象的request属性
        }

        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)
    {
        if ($request instanceof static) { // 如果传入的$request是Illuminate\Http\Request对象则直接返回。
            return $request;
        }

        $content = $request->content; // 读取request中的内容

        $request = (new static)->duplicate(
            $request->query->all(), $request->request->all(), $request->attributes->all(),
            $request->cookies->all(), $request->files->all(), $request->server->all()
        ); // 克隆一个新的对象将SymfonyRequest中的参数覆盖其中的部分参数。

        $request->content = $content; // 重新赋值给Illuminate\Http\Request对象。

        $request->request = $request->getInputSource(); // 获取请求中的数据

        return $request; // 返回Illuminate\Http\Request对象
    }
复制代码

laravel中的请求是在SymfonyRequest的基础进行继承,同时增加了自己的一些方法进去。 最终在框架中直接使用的是Illuminate\Http\Request对象。

当然请求类里面还有很多其他附带的方法,但是目前只分析在框架启动过程中请求对象 是如何发挥作用的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值