在進入正題以前,須要重點說一下 make 方法。由於從上個版本使用過來的人已經開始接受 Container 這個概念了,這個新版本的加強了 Container 的功能,建立 Request 對象的精髓就在 make 方法。倒不如說整個框架核心類都在使用這個方法。咱們來看一下這個方法是如何建立對象的。具體說明請看每一段的註釋laravel
public function make(string $abstract, array $vars = [], bool $newInstance = false) { // 首先說明 instances 屬性是一個數組,就是主要存儲容器對象 // 若是對象存在與容器中而且不須要從新建立的話,就直接從容器中獲取 if (isset($this->instances[$abstract]) && !$newInstance) { return $this->instances[$abstract]; } // bind 屬性從上一個應用初始化已經接觸到了, // 就是容器對象的綁定標識,和 instances 數組不一樣的是, // 它只是存儲了一個類字符串而已,須要實例化後獲取對象實例,下面就是實現的該功能 // 若是 bind 標識存在 if (isset($this->bind[$abstract])) { // 從 bind 獲取 $concrete = $this->bind[$abstract]; // concrete 多是一個類名或者是一個匿名函數 // 匿名函數直接執行 if ($concrete instanceof Closure) { $object = $this->invokeFunction($concrete, $vars); } else { // 不然繼續 make 建立,由於此時還沒建立出對象 return $this->make($concrete, $vars, $newInstance); } } else { // 若是沒有在標識中 說明須要的類名真正的產出了,須要實例化。 // 其實這裏纔是真正的建立類,而且下面的方法直接依賴注入 $object = $this->invokeClass($abstract, $vars); } // 對於不須要建立實例的類 直接放在容器中管理 if (!$newInstance) { $this->instances[$abstract] = $object; } // 最後返回對象 return $object; }
可能到這裏看的仍是有點糊塗,正好在這裏用 Request 建立來梳理一下。咱們來看看建立 Request 的過程。面試
下面這段代碼能夠的 run
方法中找到,這段代碼須要仔細推敲,否則你沒法知道這個 Request
對象究竟是哪一個?sql
//自動建立request對象 $request = $request ?? $this->app->make('request', [], true); $this->app->instance('request', $request);
$newInstance 在 Request 建立時被設置爲了 true,說明每次請求都須要從新建立。此時 instances 還未有 Request 對象,因此繼續忽略。
在進入 bind 以前,先看看 bind 裏面都有什麼了?shell
array(22) { ["app"]=> string(9) "think\App" ["cache"]=> string(11) "think\Cache" ["config"]=> string(12) "think\Config" ["console"]=> string(13) "think\Console" ["cookie"]=> string(12) "think\Cookie" ["db"]=> string(8) "think\Db" ["env"]=> string(9) "think\Env" ["event"]=> string(11) "think\Event" ["http"]=> string(10) "think\Http" ["lang"]=> string(10) "think\Lang" ["log"]=> string(9) "think\Log" ["middleware"]=> string(16) "think\Middleware" ["request"]=> string(13) "think\Request" ["response"]=> string(14) "think\Response" ["route"]=> string(11) "think\Route" ["session"]=> string(13) "think\Session" ["validate"]=> string(14) "think\Validate" ["view"]=> string(10) "think\View" ["filesystem"]=> string(16) "think\Filesystem" ["Psr\Log\LoggerInterface"]=> string(9) "think\Log" ["think\Request"]=> string(11) "app\Request" ["think\exception\Handle"]=> string(19) "app\ExceptionHandle" }
默認已經有了不少類名,這些都是框架默認的,不須要管,咱們只看 request 鍵名和 ‘think\Request‘,還有最後兩個 think\Request
和 think\exception\Handle
是在框架初始化注入進來的,不清楚的能夠看上一節。think\Request
就是在那個時候注入的。數組
下面進入正題,很明顯 'request' 在存在與 bind 中的,而且 request 的值並非一個匿名函數,而是一個字符串 think\Request
,只能繼續 make 建立,找到 think\Request
對應的值 app\Request
,它並不存在與 bind 中,因此直接來解析這個類名。這裏大概就明白了,實際框架並無在使用 think\Request 對象,而是 app\Request 對象。在解析後,Request 對象也被放進了容器了。下面就是請求的執行過程了。服務器
更多學習內容能夠訪問【對標大廠】精品PHP架構師教程目錄大全,只要你能看完保證薪資上升一個臺階(持續更新)cookie
以上內容但願幫助到你們,不少PHPer在進階的時候總會遇到一些問題和瓶頸,業務代碼寫多了沒有方向感,不知道該從那裏入手去提高,對此我整理了一些資料,包括但不限於:分佈式架構、高可擴展、高性能、高併發、服務器性能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優化、shell腳本、Docker、微服務、Nginx等多個知識點高級進階乾貨須要的能夠免費分享給你們,須要的能夠點擊連接領取進階PHP月薪30k>>>架構師成長路線【視頻、面試文檔免費獲取】session
本文由博客羣發一文多發等運營工具平臺 OpenWrite 發佈架構