<section id="nice" data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="line-height: 1.6; word-break: break-word; overflow-wrap: break-word; font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc cambria cochin georgia times new roman serif padding: font-size: color: rgb word-spacing: letter-spacing: border-radius:><blockquote class="multiquote-1" data-tool="mdnice编辑器" style="border: none; font-size: 0.9em; overflow: auto; margin-bottom: 20px; margin-top: 20px; padding: 15px 10px; line-height: 1.75; border-radius: 13px; color: rgb(53, 53, 53); background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial;"> <span style="display: block; font-size: 2em; color: rgb(248, 57, 41); font-family: Arial, serif; line-height: 1em; font-weight: 700;">「</span><p style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; font-size: 16px; margin: 0px 10px;">本文會對控制器最後的執行流程和使用的兩個高階屬性進行簡單的學習,一個是fastcgi_finish_request方法巧用,另一個是trait特性,超類的概念多少都有過了解,接下來一起來解析一下。 </p> <span style="float: right; display: block; font-size: 2em; color: rgb(248, 57, 41); font-family: Arial, serif; line-height: 1em; font-weight: 700;"></span> </blockquote>##當執行完控制器中的方法回應資料給App類別的run方法,直到這裡就已經執行完了。 <h1 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; color: black; border-top: 2px solid rgb(248, 57, 41); text-align: center; font-size: 1.3em;"> <span class="prefix" style="display: none;">是不是有點懵這裡的資料最後會回傳哪裡呢! </span><span class="content" style="display: inline-block; font-weight: normal; background: rgb(248, 57, 41); color: #ffffff; padding: 3px 10px 1px; border-radius: 0 0 13px 13px;"></span><span class="suffix">執行應用程式</span> </h1> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">之前寫過的框架執行流程、路由、控制器實例化都是從這裡開始進入的。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">所以當run方法執行完成之後,就會把對應的結果給回到這裡。 </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201112174307766.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">執行應用程式並回應</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">這部分的程式碼</p>Container::get('app')<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">應該都知道了是返回一個App類別的實例。 </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;">然後透過App類別去執行run方法,才會有之前講過的一切。 <img src="https://img-blog.csdnimg.cn/20201112174500611.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">下圖是喀喀爾從半中腰做的一個心智圖,前面的沒有,後邊的所有知識點都會寫在這個心智圖裡。 </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201112175009963.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">執行流程</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">執行完run方法就會去執行<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(271, 93, 108);">Container::get('app')->run()- >send()</code>send這個方法,有多少人會認為在App類別裡邊執行send方法。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">其實不是的,回想一下之前執行控制器方法然後回傳的回應結果是什麼? </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">如果你不是很粗略的看都會記得是Response的一個物件實例。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">所以說send方法會去response類別裡邊去執行。 </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201112175854478.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">傳送資料到客戶端</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">先不看其它的,先看這行程式碼<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(271, 93, 108);">$this->app['hook' ]</code>,現在知道是執行的那裡嗎? </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">這種形式就是透過存取陣列形式去存取物件的屬性,也就是之前解析的ArrayAccess這個類別。當存取的屬性不存在時會去執行offsetGet,然後執行魔術方法__get,最終透過make方法傳回實例,這一切的操作都是在容器中。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">對這行程式碼具體是監聽的什麼就不去做解析了。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">接著需要看處理輸出資料的這行程式碼<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(271, 93, 108);">$data = $this->getContent();</code></p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">這個方法做的事情就是將傳過來的資料賦值給本類的content屬性。 </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201112180500873.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">取得輸出資料</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">其實在取得輸出資料這個方法中,請看喀喀爾圈出來的第一個地方感覺是很沒有必要。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">可以看到根本對資料就沒有任何的處理,只是簡單的回傳了,所以說框架有好的地方也有不好的地方,只有你去閱讀了才會知道,否則你會對你經常使用的工具一無所知。 </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201112180707676.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">處理資料</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">在接著就是Trace偵錯注入,就是透過設定檔配置的,透過呼叫debug類別來實現的,這裡就不詳解了。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">然後就是快取判斷,快取會在後文中單獨拎出來講,所以也是過。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">在接下來就對回應頭的設定了,偵測 HTTP 頭是否已經發送,這塊的東西就很重要了,也是平時接觸不多的知識點了。 </p> <ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: rgb(248, 57, 41);"> <li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(53, 53, 53);">headers_sent() : 偵測HTTP 頭是否已傳送</section></li> <li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(53, 53, 53);">http_response_code() :取得/設定回應的HTTP 狀態碼</section></li> <li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(53, 53, 53);">#header : 函數向客戶端發送原始的HTTP 標頭。 </section></li> </ul> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201112181400844.png" alt="检测 HTTP 头是否已经发送" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">偵測HTTP 頭是否已經發送</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">最後一步,來了來了,它來了,它帶著echo來了,執行了一個方法<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(271, 93, 108);">$this->sendData($data);</code></p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">#給人一種媳婦熬成娘的感覺,終於來到的終點站,一個echo輸出了咔咔幾十天的心酸啊! </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">為了到達這個echo咔咔是經歷九九八十一難啊!戰鬥還未停止,同志仍需努力! </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201112181700149.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">輸出資料</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">那麼到這裡關於框架執行然後到應用程式初始化,在到路由偵測、控制器的實例化、然後返回response實例,在通過入口文件執行send方法。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">最後將資料輸出到終端,也就是echo的事情。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">雖然這裡的戰鬥結束了,但是在下面還有一個非常重要的知識點,咔咔將重新提一節來進行說明。 </p> <h1 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; color: black; border-top: 2px solid rgb(248, 57, 41); text-align: center; font-size: 1.3em;"> <span class="prefix" style="display: none;"></span><span class="content" style="display: inline-block; font-weight: normal; background: rgb(248, 57, 41); color: #ffffff; padding: 3px 10px 1px; border-radius: 0 0 13px 13px;">二、fastcgi_finish_request方法巧用</span><span class="suffix"></span> </h1> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">在上一節中透過<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(271, 93, 108);">Container::get( 'app')->run()->send();</code>在response類別中執行了send方法,輸出了資料。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">但是在輸出資料之後也執行了一個方法<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(271, 93, 108);">fastcgi_finish_request();</code>,給的註解是提高頁面回應,接下來好好來扒一扒其中的奧秘。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">在PHP官網看到這樣一段話</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">The script will still occupy a FPM process after fastcgi_finish_request(). So using it excessively for long running tasks may occupy all your toPM th pm.max_children. This will lead to gateway errors on the webserver.</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;"><span style="font-weight: 700; color: rgb(248, 57, 41);">在fastcgi_finish_request()之後,腳本仍將佔用FPM進程。 因此,對於長時間運行的任務過度使用它可能會佔用您的所有FPM線程,直到pm.max_children。 這將導致Web伺服器上的網關錯誤。 </span></p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">所以說在沒有徹底的了解這個方法之前不要輕易的在自己的專案中使用這個方法。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">接下來咔咔將使用一個案例來演示這個方法的使用,僅僅只是演示使用,如果需要使用到專案中請仔細閱讀文檔應該注意的問題。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;"><span style="font-weight: 700; color: rgb(248, 57, 41);">案例示範</span></p>#<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">公司有一個業務需要發送通知給用戶,但是由於發送時間太久,非常費時間,有可能需要好幾十秒的時間,更嚴重的會直接導致瀏覽器連接超時。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">在一個問題就是使用者體驗的問題,使用者等待時間過程,體驗當然不好。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">為了解決以上兩個問題,今天談論的<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(271, 93, 108);">fastcgi_finish_request</code>就派上了用場。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;"><span style="font-weight: 700; color: rgb(248, 57, 41);">理解</span></p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">對這個函數的理解其實就是發送回應給瀏覽器,使用者等待時間大大縮短,但是PHP進程還是在運作的。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">這樣就達到了來個目的,就類似於我們常說的非同步執行。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">直覺的來說就是發送郵件有可能需要10秒,但是用戶是沒有感知的,用戶點擊發送郵件之後直接就返回發送成功,瀏覽器響應結束,用戶做其它事情,後台進程繼續執行發送郵件的任務。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;"><span style="font-weight: 700; color: rgb(248, 57, 41);">案例</span></p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201112184659603.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">示範案例</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">#具體程式碼</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block; background: url(https://files.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #282c34; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;"></span><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; padding-top: 15px; background: #282c34; border-radius: 5px;"><span class="hljs-meta" style="color: #61aeee; line-height: 26px;"><?php</span><br/><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br/> * 设置超时时间,变成不限制<br/> *<br/> */</span><br/>set_time_limit(<span class="hljs-number" style="color: #d19a66; line-height: 26px;">0</span>);<br/><br/><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br/> * 本函数模拟非常耗时的任务,执行完毕需要5秒的时间<br/> */</span><br/><span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">function</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">writeFile</span><span class="hljs-params" style="line-height: 26px;">()</span><br/></span>{<br/> $path = <span class="hljs-string" style="color: #98c379; line-height: 26px;">'D:/phpstudy_pro/WWW/kaka.txt'</span>;<br/> file_put_contents($path,<span class="hljs-string" style="color: #98c379; line-height: 26px;">'程序运行开始'</span> . PHP_EOL,FILE_APPEND);<br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span>($i =<span class="hljs-number" style="color: #d19a66; line-height: 26px;">0</span>;$i < <span class="hljs-number" style="color: #d19a66; line-height: 26px;">5</span>;$i++) {<br/> file_put_contents($path,time() . PHP_EOL,FILE_APPEND);<br/> sleep(<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>);<br/> }<br/><br/> file_put_contents($path,<span class="hljs-string" style="color: #98c379; line-height: 26px;">'程序运行结束'</span> . PHP_EOL,FILE_APPEND);<br/><br/>}<br/><br/><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br/> * 输出文字标记,任务开始<br/> */</span><br/><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">echo</span>(<span class="hljs-string" style="color: #98c379; line-height: 26px;">'任务开始'</span>);<br/><br/><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br/> * 后台执行非常耗时的任务<br/> */</span><br/>register_shutdown_function(writeFile);<br/><br/><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br/> * 立即发送请求<br/> */</span><br/>fastcgi_finish_request();<br/><br/><br/><br/></code></pre><div class="contentsignin">登入後複製</div></div><figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/2020111218462589.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">示範結果</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">以上測試全部使用linux系統測試哈,否則你看不到直覺的效果。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">經過上面的演示,回應非常快,瀏覽器回應結束後,後台程式依然進行執行每秒執行一個時間戳。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">以上就是對<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(271, 93, 108);">fastcgi_finish_request</code>方法的簡單介紹,如果你也感興趣可以進行簡單的嘗試一下,有助於更好的去理解其中的小秘密。 </p> <h1 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; color: black; border-top: 2px solid rgb(248, 57, 41); text-align: center; font-size: 1.3em;"> <span class="prefix" style="display: none;"></span><span class="content" style="display: inline-block; font-weight: normal; background: rgb(248, 57, 41); color: #ffffff; padding: 3px 10px 1px; border-radius: 0 0 13px 13px;">三、trait特性講解</span><span class="suffix"></span> </h1> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">#應該在兩個年前咔咔就對這個特性進行過一次解析,<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(271, 93, 108);">trait</code>就是常說的超類別。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">這個特性是在PHP5.4才加入的,這個特性不是常用的介面更不是類別。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">這個特性是為了解決PHP的一大弱點只能單繼承的缺點,但是也不能叫多繼承,嚴謹一點的就是類似多繼承的功能而已。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">接下來要為大家示範一個案例。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">建立test檔一,並且傳回對應類別名稱。 </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201116111137431.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">超類別的第一個文件</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">建立test1文件,並且傳回對應類別名稱</p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201116111157956.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">超類別的第二個檔案</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">建立控制器檔案用來輸出資訊。 </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201116110800899.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">建立控制器</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">然後在控制器中引入對應的超類別文件,這裡需要注意的是圈住的第一個框,這個框就是直接引入超類別test檔。 </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201116111330860.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">在控制器中引入對應的超類別檔案</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">然後可以直接進行訪問,看看會回傳什麼。 </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201116162025947.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">返回結果</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">透過上圖存取結果結果可以看得到傳回的是Test超類別檔案的方法,但是此控制器同樣也基礎了Controller控制器,這也就是在文章一開頭就說的超類就是實作了一種多繼承的功能而已。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">但是這裡會存在一個問題,請看下圖報錯資訊。 </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201116162238580.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">報錯訊息</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">上圖的報錯訊息是因為在控制器中使用了兩個超類別導致的,也就是下圖的使用方式。 </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201116162329921.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">控制器使用兩個超類別</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">那麼要如何解決這種報錯訊息呢!接下來跟著這喀喀的節奏一起來。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;"><span style="font-weight: 700; color: rgb(248, 57, 41);">解決報錯訊息</span></p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">在解決之前問題之前得先清楚這個問題是由於什麼造成的。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">出現這個錯誤的原因是引用的兩個trait裡面有同名的hello函數,出現了衝突。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">但是在日常開發中這種情況都是可以避免的,因為手動改方法名還是很方便的,但是這裡咔咔教大家如何解決這種問題。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">一是用其中一個trait裡的hello方法覆蓋另外一個trait的同名方法,因為兩個方法內容是一致的,所以我在這裡直接選擇insteadof覆蓋;</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">二是給他們用as取別名,這樣就不會有衝突了。 as關鍵字還有另一個用途,那就是修改方法的存取控制。 </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/2020111616345563.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">解決後的方法實作</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">經過上圖的改變之後,再一次的進行訪問,看一下返回結果。 </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201116163533787.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">返回結果</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">那麼這個時候就會有夥伴有疑問了,就是案例列印結果一直是Test類別的方法,Test1類別的方法一直沒有進行列印。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">那是如何進行訪問的呢!來接著看一下。 </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201116163716892.png" alt="ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">訪問超類別2的程式碼</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">從上圖可以看到將訪問方法改為別名控制訪問,接著來看訪問結果。 </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201116163805407.png" alt="超类二ThinkPHP框架所使用的特性fastcgi_finish_request和trait" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">超類別二回傳結果</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">從上圖可以看到回傳結果就是超類別Test1類別的回傳結果。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">那麼關於as這個的使用就需要大家在去搜尋一下使用方式,有時候注意一下細節就可以學到很多知識點。 </p> <h1 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; color: black; border-top: 2px solid rgb(248, 57, 41); text-align: center; font-size: 1.3em;"> <span class="prefix" style="display: none;"></span><span class="content" style="display: inline-block; font-weight: normal; background: rgb(248, 57, 41); color: #ffffff; padding: 3px 10px 1px; border-radius: 0 0 13px 13px;">總結</span><span class="suffix"></span> </h1> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">直到這裡關於控制器的原始碼解析就到這了,喀喀爾透過原始碼給大家分析控制器的如如何進行實例化的。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">也再一次的進行了對ArrayAccess和魔術方法的呼叫關係,一定要有自己的思考去想問題。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">在就是對存取控制器後是如何進行回應資料的,等等。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">也在原始碼中學到了關於fastcgi_finish_request方法巧用,但是在使用這個函數一定要注意關於咔咔提到的兩個注意點。 </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">最後就是對超類別的一個簡單案例描述。 </p> <blockquote class="multiquote-1" data-tool="mdnice编辑器" style="border: none; font-size: 0.9em; overflow: auto; margin-bottom: 20px; margin-top: 20px; padding: 15px 10px; line-height: 1.75; border-radius: 13px; color: rgb(53, 53, 53); background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial;"> <span style="display: block; font-size: 2em; color: rgb(248, 57, 41); font-family: Arial, serif; line-height: 1em; font-weight: 700;">「</span><p style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; font-size: 16px; margin: 0px 10px;">堅持學習、堅持寫博、堅持分享是咔咔從業以來一直所秉持的信念。希望在偌大互聯網中咔咔的文章能帶給你一絲絲幫助。</p> </blockquote></figure></section>