Laravel 請求類原始碼分析

chonghua_123發表於2019-02-28

前言 只為學習

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 協議》,轉載必須註明作者和本文連結

相關文章