
1)kernel.requestEvent 實現kernel.request事件目的是為了添加更多信息到Request對象,或者得到返回的Response對象(例如:從緩存中獲取又或者security層拒絕訪問) kernel.request事件是HttpKernel::handle()調度的第一個事件,那么監聽該事件的多個監聽器就會被執行。
監聽kernel.request事件的監聽器多種多樣,它們的行為各不相同,例如security監聽器判斷用戶沒有足夠的權限的時候一個RedirectResponse對象,如果當前直接返回Response對象,那么就會直接執行 kernel.response 事件:
其它的監聽器實現一些初始化或者添加更多的信息到Request對象。 例如路由監聽器,路由監聽器從Request對象中獲取路由相關的信息,經過進一步加工,確定處理請求的Controller,并且把相應的信息保存到Request對象里的‘attribute’里,這些信息都會被Controller解析器使用的,所以可以實現監聽器之間的解耦。 總得來說,實現kernel.request事件的目的要么就是直接創建和返回Response對象,要么就是添加更多的信息到Request對象。RouterListener是Symfony框架中實現kernel.request事件的最重要監聽器,RouterListener在路由層中執行,返回一個包含符合當前請求的路由信息的數組,例如路由匹配模式里面的_controller和請求的參數({name})。這些信息都會存放在Request里的attributes數組里面,目前只是會添加路由信息到Request對象中還沒有做其它的動作,但是解析Controller的時候會被用到。2) Resolve the Controller 假設實現kernel.request事件的時候沒有創建和返回Response對象,那么下一步就是確定、解析controller和controller需要的參數。controller部分是應用層的最后一個堡壘,負責創建和返回包含一個特定頁面的Response對象。如何確定被請求的controller完全取決于應用程序,這個工作有controller解析器來完成——一個是實現ControllerResolverInterface的類,同時也是HttpKernel構造函數的一個參數。

實現ControllerResolverInterface的兩個方法getController和getArguments:
HttpKernel::handle()首先調用controller resolver 的 getController()方法,并向該方法傳入Request對象,controller resolver根據Request包含的信息確定并返回controller。 第二個方法,getArguments()會在kernel.controller事件被調度的時候執行。解析ControllerSymfony框架使用內置的ControllerResolver(實質上是使用了一個有額外的功能的子類),該解析器利用了RouterListener保存到Request對象的attributes屬性里信息來確定controller。getControllerControllerResolver在Request對象的attributes數組中查找 _controller 鍵(這些信息實際上是由RouterListener存放進Request對象中的):a) 如果_controller 鍵對應AcmeDemoBundle:Default:index 這個格式的值,那么該值就包含了類名和方法名,可以被Symfony框架解析成為,例如:Acme/DemoBundle/Controller/DefaultController::indexAction,這個轉換是由Symfony框架的特定的ControllerResolver的子類完成的。b) 你的controller類會被實例化,而且該controller類必須包含一個無參的構造函數。c) 如果你的controller還實現了ContainerAwareInterface,那么setContainer方法就會被調用,container就會被注入到controller中,這個實現也是由Symfony框架的特定的ControllerResolver的子類完成的。上面也有一些其他變化過程,例如你把你的controller配置成為service。3) The
kernel.controllerEventkernel.controller事件是在controller被執行前初始化一些信息或者改變controller對象。
被調用的controller確定之后,HttpKernel::handle()就會調度kernel.controller事件。在系統的某部分被確定后(例如:controller、路由信息等)但是這些部分被執行前,監聽kernel.controller事件的監聽器就會運行了。


kernel.controllerSymfony框架有幾個kernel.controller事件的監聽器,多數都是處理分析數據的。SensioFrameworkExtraBundle中一個監聽器ParamConverter允許我們把一個對象作為參數傳入到controller中,而不是字符串或者數值參數。4)獲得controller的參數 getAttributes()方法是返回一個參數數組,這個參數數組會被傳遞給controller,我們也可以自定義該方法,也可以使用Symfony框架內置的。


到了這一步,kernel已經獲得了controller和controller運行時需要的參數了。
Symfony框架獲得controller的參數
ControllerResolver使用放射機制獲得被調用的controller的方法的參數列表。遍歷該列表,使用下面的步驟來確定參數列表中一一對應的值:a) 使用參數作為鍵查找Request對象中的attributes數組,如果找到,那么相應的值會傳入到controller的方法中,例如:controller方法的第一個參數是$name,那么在Request的attributes數組中包含$attributes['name']的值,那么$attributes['name']就會被使用。
b) 如果該該參數在Symfony配置routing的時候被指定,那么就會跳過對該參數的查找。
5)調用controller
這一步,controller就會被執行。
controller會創建包含特定頁面或者json的Response對象,這也是應用層的最后一個步驟。
如果controller返回的是Response對象,那么下一步kernel.response事件就會觸發,否者kernel.view事件就會被觸發。controller必須要有返回值,如果返回null,程序會報錯
6) kernel.view事件
c
新聞熱點
疑難解答