Laravel 请求类源码分析

前言 只为学习

Illuminate\Http\Request

1. 引入

use Closure; //匿名函数
use ArrayAccess; //spl  array
use RuntimeException; //运行异常类
use Illuminate\Support\Arr; //框架基础支持的数组类
use Illuminate\Support\Str; //框架基础支持的字符串类
use Illuminate\Support\Traits\Macroable; //框架基础的宏指令类
use Illuminate\Contracts\Support\Arrayable; //框架基础的数组比较类
use Symfony\Component\HttpFoundation\ParameterBag; //Symfony 基础请求包类
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;//Symfony 基础请求类

2. 声明Request类

class Request extends SymfonyRequest implements Arrayable, ArrayAccess
{
    use Concerns\InteractsWithContentTypes,
        Concerns\InteractsWithFlashData,
        Concerns\InteractsWithInput,
        Macroable;

    /**
     * The decoded JSON content for the request.
     * 请求解码的json内容
     * @var \Symfony\Component\HttpFoundation\ParameterBag|null
     */
    protected $json;

    /**
     * All of the converted files for the request.
     * 为请求转换的所有文件
     * @var array
     */
    protected $convertedFiles;

    /**
     * The user resolver callback.
     * 用户冲突解决程序回调
     * @var \Closure
     */
    protected $userResolver;

    /**
     * The route resolver callback.
     * 路由冲突回调
     * @var \Closure
     */
    protected $routeResolver;

3. capture创建新的请求类

1、static::enableHttpMethodParameterOverride()
2、SymfonyRequest::createFromGlobals()
3、createFromBase

public static function capture()
    {
        static::enableHttpMethodParameterOverride();//启用对方法请求参数的支持以确定预期的HTTP方法
        return static::createFromBase(SymfonyRequest::createFromGlobals());
        //感觉可以return static::createFromBase(static::createFromGlobals());//这么写(原因可能是为了防止子类重载父类静态方法)
    }

4. instance 返回当前请求实例

public function instance()
    {
        return $this;
    }

5. method 获取当前请求方法

1、getMethod

public function method()
    {
        return $this->getMethod();
    }

6. root 获取应用程序的根URL

1、getSchemeAndHttpHost
2、getBaseUrl

    public function root()
    {
        return rtrim($this->getSchemeAndHttpHost().$this->getBaseUrl(), '/');
    }

7. url 获取没有参数的url

1、getUri

public function url()
    {
        return rtrim(preg_replace('/\?.*/', '', $this->getUri()), '/');
    }

8. fullUrl 获取全部url

1、getQueryString
2、getBaseUrl
3、url

public function fullUrl()
    {
        $query = $this->getQueryString();

        $question = $this->getBaseUrl().$this->getPathInfo() === '/' ? '/?' : '?';

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

9. fullUrlWithQuery 使用添加的查询字符串参数获取请求的完整URL

1、getBaseUrl
2、query
3、url
4、fullUrl

public function fullUrlWithQuery(array $query)
    {
        $question = $this->getBaseUrl().$this->getPathInfo() === '/' ? '/?' : '?';

        return count($this->query()) > 0
            ? $this->url().$question.Arr::query(array_merge($this->query(), $query))
            : $this->fullUrl().$question.Arr::query($query);
    }

10. path 获取当前请求路径

1、getPathInfo

public function path()
    {
        $pattern = trim($this->getPathInfo(), '/');

        return $pattern == '' ? '/' : $pattern;
    }

11. decodedPath 解码后的路径

public function decodedPath()
    {
        return rawurldecode($this->path());
    }

12. segment 从url字符串获取一段

1、segments

public function segment($index, $default = null)
    {
        return Arr::get($this->segments(), $index - 1, $default);
    }

13. segments

1、decodedPath

public function segments()
    {
        $segments = explode('/', $this->decodedPath());

        return array_values(array_filter($segments, function ($value) {
            return $value !== '';
        }));
    }

14. is 确定当前请求URI是否与模式匹配

1、is
2、decodedPath

public function is(...$patterns)
    {
        foreach ($patterns as $pattern) {
            if (Str::is($pattern, $this->decodedPath())) {
                return true;
            }
        }
        return false;
    }

15. routeIs 检测路由名称是否匹配

1、route

public function routeIs(...$patterns)
    {
        return $this->route() && $this->route()->named(...$patterns);
    }

16. fullUrlIs

1、fullUrl

public function fullUrlIs(...$patterns)
    {
        $url = $this->fullUrl();

        foreach ($patterns as $pattern) {
            if (Str::is($pattern, $url)) {
                return true;
            }
        }
        return false;
    }

17. ajax 判断是否ajax

public function ajax()
    {
        return $this->isXmlHttpRequest();
    }

18. pjax 判断是否pjax请求

public function pjax()
    {
        return $this->headers->get('X-PJAX') == true;
    }

19. secure 判断请求是否安全

1、isSecure

public function secure()
    {
        return $this->isSecure();
    }

20. ip 获取客户端ip

1、getClientIp

public function ip()
    {
        return $this->getClientIp();
    }

21. ips 获取客户端全部代理ip

1、getClientIps

public function ips()
    {
        return $this->getClientIps();
    }

22. userAgent 获取浏览器头

1、get()

public function userAgent()
    {
        return $this->headers->get('User-Agent');
    }

23. merge 合并请求参数

1、getInputSource 获取请求输入参数来源

public function merge(array $input)
    {
        $this->getInputSource()->add($input);

        return $this;
    }

24. replace 替换请求参数

1、getInputSource

public function replace(array $input)
    {
        $this->getInputSource()->replace($input);

        return $this;
    }

25. get 获取请求参数并设置默认值

1、parent::get

public function get($key, $default = null)
    {
        return parent::get($key, $default);
    }

26. json 获取请求的json

public function json($key = null, $default = null)
    {
        if (! isset($this->json)) {
            $this->json = new ParameterBag((array) json_decode($this->getContent(), true));//解析
        }

        if (is_null($key)) {
            return $this->json;
        }

        return data_get($this->json->all(), $key, $default);
    }

27. getInputSource 获取请求参数来源

protected function getInputSource()
    {
        if ($this->isJson()) {
            return $this->json();
        }
        return in_array($this->getRealMethod(), ['GET', 'HEAD']) ? $this->query : $this->request;
    }

28. createFrom 从给定的Laravel请求创建一个新的请求实例

public static function createFrom(self $from, $to = null)
    {
        $request = $to ?: new static;

        $files = $from->files->all();

        $files = is_array($files) ? array_filter($files) : $files;

        $request->initialize(
            $from->query->all(),
            $from->request->all(),
            $from->attributes->all(),
            $from->cookies->all(),
            $files,
            $from->server->all(),
            $from->getContent()
        );

        $request->setJson($from->json());

        if ($session = $from->getSession()) {
            $request->setLaravelSession($session);
        }

        $request->setUserResolver($from->getUserResolver());

        $request->setRouteResolver($from->getRouteResolver());

        return $request;
    }

29. createFromBase 从symfony实例创建请求实例

1、

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;
    }

30. duplicate

1、duplicate
2、parent::duplicate

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); 
    }

31. filterFiles 递归过滤文件

    protected function filterFiles($files)
    {
        if (! $files) {
            return;
        }
        foreach ($files as $key => $file) {
            if (is_array($file)) {
                $files[$key] = $this->filterFiles($files[$key]);
            }
            if (empty($files[$key])) {
                unset($files[$key]);
            }
        }
        return $files;
    }

32. session 获取session

1、hasSession

public function session()
    {
        if (! $this->hasSession()) {
            throw new RuntimeException('Session store not set on request.');
        }

        return $this->session;
    }

33. getSession 获取session

public function getSession()
    {
        return $this->session;
    }

34. setLaravelSession 设置session

public function setLaravelSession($session)
    {
        $this->session = $session;
    }

35. user

1、getUserResolver

public function user($guard = null)
    {
        return call_user_func($this->getUserResolver(), $guard);
    }

36. route

1、getRouteResolver
2、parameter

public function route($param = null, $default = null)
    {
        $route = call_user_func($this->getRouteResolver());
        if (is_null($route) || is_null($param)) {
            return $route;
        }
        return $route->parameter($param, $default);
    }

37. fingerprint 获取请求/路由/IP地址的唯一sha1加密串

public function fingerprint()
    {
        if (! $route = $this->route()) {
            throw new RuntimeException('Unable to generate fingerprint. Route unavailable.');
        }

        return sha1(implode('|', array_merge(
            $route->methods(),
            [$route->getDomain(), $route->uri(), $this->ip()]
        )));
    }

38. setJson

public function setJson($json)
    {
        $this->json = $json;

        return $this;
    }

39. 获取用户解析程序回调

public function getUserResolver()
    {
        return $this->userResolver ?: function () {
            //
        };
    }

40. setUserResolver 设置用户解析程序回调

public function setUserResolver(Closure $callback)
    {
        $this->userResolver = $callback;

        return $this;
    }

41. getRouteResolver 获取路由解析回调

public function getRouteResolver()
    {
        return $this->routeResolver ?: function () {
            //
        };
    }

42. setRouteResolver 设置路由解析回调

public function setRouteResolver(Closure $callback)
    {
        $this->routeResolver = $callback;

        return $this;
    }

43. toArray 获取请求的所有输入和文件

1、all

public function toArray()
    {
        return $this->all();
    }
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!