做者:老王
更新:鑑於我最初的行文方式有讓人誤解之嫌,因此我對措辭作了適當的刪減,使之更簡明扼要。
所謂前端控制器(FrontController),是指一個請求運行的公共起點,而且在這裏決定下一步執行什麼。
多數PHP框架裏都實現了它。統一進行權限限制,會話管理等等公共操做,而且進而經過一個相似路由的裝置,把請求委派給一個具體的命令對象來執行。實現方式上,前端控制器一般是以一個名爲index.php的文件爲載體,經過重寫規則把請求都轉發到這個文件上,如CakePHP在Apache上的設置:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>
不過老話說,物極必反,隨着前端控制器使用的泛濫,愈來愈多的人開始質疑PHP開發是否有必要使用前端控制器。這裏以PHP之父Rasmus Lerdorf的影響最大,早些時候,他在Simple is Hard裏陳述了若是想開發出有擴展性的Web應用,必須保證架構是Share-nothing Architecture:
Share-nothing Architecture
* Like HTTP, each request is distinct
* Shared data is pushed down to the data-store layer
* Avoid front controllers
在Rasmus Lerdorf看來,想要讓一個網站具備良好的擴展性實際上是很是簡單的,只需將網站應用分紅若干個獨立小程序,前端透過API提供服務,後端是應用程序引擎,這樣作天然會有擴展性。由於應用的每個部分,都有不一樣等級的使用方式,須要有不一樣的擴充程度,須要不一樣的機制來處理。以開發雅虎電子郵件而言,是要開發一個地址服務程序、一個讀信服務、一個送信服務,而送信程序徹底和讀信程序無關。以雅虎的規模而言,須要讓這些工做徹底分離,纔有擴充性。這裏的關鍵是你必須創建分離、模塊化的獨立端點,而不是所有放在同一個大籃子裏。大多數現今開發框架,都使用了前端控制器,每一次瀏覽器發出請求時,就會調用這個前端控制器,再由前端控制器來分辨,使用者想要執行哪一支程序。這樣作,一點意義都沒有。在瀏覽器層次,程序徹底能知道用戶想要作什麼事情,例如使用者只是要讀信,程序就不用再把需求送到服務器,讓服務器判斷使用者要讀信仍是送信。將這類決策工做拉出瀏覽器,由服務器處理,就會浪費大量服務器資源,來處理那些對用戶沒有實際功用的工做。php
總結:
首先,前端控制器裏存在一個路由轉發的過程,這個過程是在服務端完成的,無論是什麼請求都要經由前端控制再完成路由轉發,這個過程極可能會引發性能問題。若是拋棄了前端控制器的作法,轉而使用頁面控制器的實現方式,那麼服務端就沒必要再存在路由轉發的過程,由於在把頁面渲染到瀏覽器上的時候,天然而然就完成了路由的設定,不一樣的動做對應着不一樣的URL。功能實現則徹底由頁面控制器來實現。若是某個動做引發了性能的瓶頸,那麼咱們只要針對這個動做對應的URL增長更多的服務器就能夠完成擴展。
另外,傳統的MVC理論裏,強調代碼邏輯上的分離,但並未就物理分離作出描述,Rasmus Lerdorf在這方面作出了有益的補充,按Rasmus Lerdorf的引伸想法,M和V是分別位於不一樣服務器的,V經過WebService調用M上的數據。
請牢記Rasmus Lerdorf的教誨。
參考連接:Rasmus 校園講座臺大場:Simple is Hard前端