您好,登錄后才能下訂單哦!
小編給大家分享一下ThinkPHP框架如何使用fastcgi_finish_request和trait,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
當執行完控制器中的方法響應數據給App類的run方法,直到這里就已經執行完了。
是不是有點懵這里的數據最終會返回哪里呢!
之前寫過的框架執行流程、路由、控制器實例化都是從這里開始進入的。
所以當run方法執行完成之后,就會把對應的結果給返回到這里。
這一部分的代碼Container::get('app')
應該都知道了是返回一個App類的實例。
然后通過App類去執行run方法,才會有之前講過的一切。
下圖是咔咔從半中腰做的一個思維導圖,前面的沒有,后邊的所有知識點都會寫在這個思維導圖里。
執行完run方法就會去執行Container::get('app')->run()->send()
send這個方法,有多少人會認為在App類里邊執行send方法。
其實不是的,回想一下之前執行控制器方法然后返回的響應結果是什么?
如果你不是很粗略的看都會記得是Response的一個對象實例。
所以說send方法會去response類里邊去執行。
先不看其它的,先看這行代碼$this->app['hook']
,現在知道是執行的那里嗎?
這種形式就是通過訪問數組形式去訪問對象的屬性,也就是之前解析的ArrayAccess這個類。當訪問的屬性不存在時會去執行offsetGet,然后執行魔術方法__get,最終通過make方法返回實例,這一切的操作都是在容器中。
對這行代碼具體是監聽的什么就不去做解析了。
接著需要看處理輸出數據的這行代碼$data = $this->getContent();
這個方法做的事情就是將傳過來的數據賦值給本類的content屬性。
其實在獲取輸出數據這個方法中,請看咔咔圈出來的第一個地方感覺是很沒有必要。
可以看到根本對數據就沒有任何的處理,只是簡單的返回了,所以說框架有好的地方也有不好的地方,只有你去閱讀了才會知道,否則你會對你經常使用的工具一無所知。
在接著就是Trace調試注入,就是通過配置文件配置的,通過調用debug類實現的,這里就不詳解了。
然后就是緩存判斷,緩存會在后文中單獨拎出來講,所以也是過。
在接下來就對響應頭的設置了,檢測 HTTP 頭是否已經發送,這塊的東西就很重要了,也是平時接觸不多的知識點了。
最后一步,來了來了,它來了,它帶著echo來了,執行了一個方法$this->sendData($data);
給人一種媳婦熬成娘的感覺,終于來到的終點站,一個echo輸出了咔咔幾十天的心酸啊!
為了到達這個echo咔咔是經歷九九八十一難啊!戰斗還未停止,同志仍需努力啊!
那么到這里關于框架執行然后到應用初始化,在到路由檢測、控制器的實例化、然后返回response實例,在通過入口文件執行send方法。
最后將數據輸出到終端,也就是一個echo的事情。
雖然這里的戰斗結束了,但是在下面還有一個非常重要的知識點,咔咔將重新提一節來進行說明。
在上一節中通過Container::get('app')->run()->send();
在response類中執行了send方法,輸出了數據。
但是在輸出數據之后還執行了一個方法fastcgi_finish_request();
,給的注釋是提高頁面響應,接下來好好來扒一扒其中的奧秘。
在PHP官網中看到這樣一段話
The script will still occupy a FPM process after fastcgi_finish_request(). So using it excessively for long running tasks may occupy all your FPM threads up to pm.max_children. This will lead to gateway errors on the webserver.
在fastcgi_finish_request()之后,腳本仍將占用FPM進程。 因此,對于長時間運行的任務過度使用它可能會占用您的所有FPM線程,直到pm.max_children。 這將導致Web服務器上的網關錯誤。
所以說在沒有徹底的了解這個方法之前不要輕易的在自己的項目中使用這個方法。
接下來咔咔將使用一個案例來演示這個方法的使用,僅僅只是演示使用,如果需要使用到項目中請仔細閱讀文檔應該注意的問題。
案例演示
公司有一個業務需要發送通知給用戶,但是由于發送時間太久,非常費時間,有可能需要好幾十秒的時間,更嚴重的會直接導致瀏覽器連接超時。
在一個問題就是用戶體驗的問題,用戶等待時間過程,體驗當然不好。
為了解決以上倆個問題,今天談論的fastcgi_finish_request
就派上了用場。
理解
對這個函數的理解其實就是發送響應給瀏覽器,用戶等待時間大大縮短,但是PHP進程還是在運行的。
這樣就達到了來個目的,就類似于我們經常說的異步執行。
直觀的來說就是發送郵件有可能需要10秒,但是用戶是沒有感知的,用戶點擊發送郵件之后直接就返回發送成功,瀏覽器響應結束,用戶做其它事情,后臺進程繼續執行發送郵件的任務。
案例
具體代碼
<?php
/**
* 設置超時時間,變成不限制
*
*/
set_time_limit(0);
/**
* 本函數模擬非常耗時的任務,執行完畢需要5秒的時間
*/
function writeFile()
{
$path = 'D:/phpstudy_pro/WWW/kaka.txt';
file_put_contents($path,'程序運行開始' . PHP_EOL,FILE_APPEND);
for($i =0;$i < 5;$i++) {
file_put_contents($path,time() . PHP_EOL,FILE_APPEND);
sleep(1);
}
file_put_contents($path,'程序運行結束' . PHP_EOL,FILE_APPEND);
}
/**
* 輸出文字標記,任務開始
*/
echo('任務開始');
/**
* 后臺執行非常耗時的任務
*/
register_shutdown_function(writeFile);
/**
* 立即發送請求
*/
fastcgi_finish_request();
以上測試全部使用linux系統進行測試哈,否則你看不到直觀的效果。
經過上面的演示,響應非常快,瀏覽器響應結束后,后臺程序依然進行執行每秒執行一個時間戳。
以上就是對fastcgi_finish_request
方法的簡單介紹,如果你也感興趣可以進行簡單的嘗試一下,有助于更好的去理解其中的小秘密。
應該在倆年前咔咔就對這個特性進行過一次解析,trait
就是常說的超類。
這個特性是在PHP5.4才加入的,這個特性不是經常使用的接口更不是類。
這個特性是為了解決PHP的一大弱點只能單繼承的缺點,但是也不能叫多繼承,嚴謹一點的就是類似多繼承的功能而已。
接下來給大家演示一個案例。
創建test文件一,并且返回對應類名。
創建test1文件,并且返回對應類名
創建控制器文件用來輸出信息。
然后在控制器中引入對應的超類文件,這里需要注意的是圈住的第一個框,這個框就是直接引入超類test文件。
然后可以直接進行訪問,看會返回什么。
通過上圖訪問結果結果可以看得到返回的是Test超類文件的方法,但是此控制器同樣也基礎了Controller控制器,這也就是在文章一開頭就說的超類就是實現了一種多繼承的功能而已。
但是這里會存在一個問題,請看下圖報錯信息。
上圖的報錯信息是因為在控制器中使用了倆個超類導致的,也就是下圖的使用方式。
那么如何解決這種報錯信息呢!接下來跟這咔咔的節奏一起來。
解決報錯信息
在解決之前問題之前得先清楚這個問題是由于什么引起的。
出現這個錯誤的原因是引用的兩個trait里面有同名的hello函數,出現了沖突。
但是在日常開發中這種情況都是可以避免的,因為手動改方法名還是很方便的,但是這里咔咔教大家如何解決這種問題。
一是用其中一個trait里的hello方法覆蓋另外一個trait的同名方法,因為兩個方法內容是一致的,所以我這里直接選擇insteadof覆蓋;
二是給他們用as起別名,這樣就不會有沖突了。as關鍵詞還有另外一個用途,那就是修改方法的訪問控制。
經過上圖的改動之后,再一次的進行訪問,看一下返回結果。
那么這個時候就會有伙伴有疑問了,就是案例打印結果一直是Test類的方法,Test1類的方法一直沒有進行打印。
那是如何進行訪問的呢!來接著看一下。
從上圖可以看到將訪問方法改為了別名控制訪問,接著來看一下訪問結果。
從上圖中可以可以看到返回結果就是超類Test1類的返回結果。
那么關于as這個的使用就需要大家在去搜索一下使用方式,有時候注意一下細節就可以學到很多知識點。
直到這里關于控制器的源碼解析就到這了,咔咔通過源碼給大家分析控制器的如如何進行實例化的。
也再一次的進行了對ArrayAccess和魔術方法的調用關系,一定要有自己的思考去想問題。
在就是對訪問控制器后是如何進行響應數據的,等等。
也在源碼中學到了關于fastcgi_finish_request方法巧用,但是在使用這個函數一定要注意關于咔咔提到的倆個注意點。
最后就是對超類的一個簡單案例描述。
看完了這篇文章,相信你對“ThinkPHP框架如何使用fastcgi_finish_request和trait”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。