獲取 Request 對像
在進入正題之前,需要重點說一下 make 方法,因為從上個版本使用過來的人已經開始接受 Container 這個概念了,這個新版本的增強了 Container 的功能,創建 Request 物件的精髓就在 make 方法,倒不如說整個框架核心類都在使用這個方法,我們來看一下這個方法是如何創建物件的,具體說明請看每一段的注釋
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 物件到底是哪個?
//自動創建request物件
$request = $request ?? $this->app->make('request', [], true);
$this->app->instance('request', $request);
$newInstance 在 Request 創建時被設定為了 true,說明每次請求都需要重新創建,此時 instances 還未有 Request 物件,所以繼續忽略,
在進入 bind 之前,先看看 bind 里面都有什么了?
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架構師教程目錄大全,只要你能看完保證薪資上升一個臺階(持續更新)
以上內容希望幫助到大家,很多PHPer在進階的時候總會遇到一些問題和瓶頸,業務代碼寫多了沒有方向感,不知道該從那里入手去提升,對此我整理了一些資料,包括但不限于:分布式架構、高可擴展、高性能、高并發、服務器性能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優化、shell腳本、Docker、微服務、Nginx等多個知識點高級進階干貨需要的可以免費分享給大家,需要的可以點擊鏈接領取進階PHP月薪30k>>>架構師成長路線【視頻、面試檔案免費獲取】
本文由博客群發一文多發等運營工具平臺 OpenWrite 發布
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/1936.html
標籤:PHP
上一篇:關于兩個經緯度之間的距離計算
