Laravel Controller中的callAction
前言:
我們都知道在Laravel的router中定義好路徑,並且指定到要執行的controller method中,連到該路徑就會進入指定的method中執行,
但是在這之前Laravel做了多少事情才讓資料流進入到到controller method中呢?今天我們來往前走一步,那就是controller中的callAction method
參考資料
callAction做了什麼
在我們自己定義的Controller中,都會去繼承Laravel framework中的BaseController,裡面就有個method大致上如下
| 
					 1 2 3 4 5  | 
						public function callAction($method, $parameters) {     // ... 你的邏輯     return $this->{$method}(...array_values($parameters)); }  | 
					
大致上就是用動態呼叫的方式把call你在router中定義的method name,以及將參數送過去
簡單來說,callAction會是你定義的controller method的進入點以及離開點,所以我們可以複寫controller中的callAction method來達到進入controller處理邏輯前做一些,以及邏輯處理完return資料前再做一些事情
我們改了什麼
我們先覆寫controller中的callAction method
| 
					 1 2 3 4 5 6 7  | 
						public function callAction($method, $parameters): array|ServerResponse {     $ctx = new RequestCtx(method: $method, parameters: $parameters);     $this->_pre_call($ctx);     $this->_call($ctx);     return $this->_post_call($ctx); }  | 
					
其中,我們自行定義一個RequestCtx Class,目的在於存下原本controller的傳入值以及預計要return的回傳值,方便處理
我們分成三個動作,_pre_call, _call, 以及_post_call 三個動作,分別是預先處理資料、真正呼叫controller method 做事情,最後處理retrun 值
| 
					 1 2 3 4 5  | 
						protected function _pre_call(RequestCtx $ctx): RequestCtx {     ...     return $ctx; }  | 
					
_pre_call比較不重要,這邊就先不描述,主要就是針對傳入值做一些進入controller前需要的init或是validate
| 
					 1 2 3 4 5 6  | 
						protected function _call(RequestCtx $ctx): RequestCtx {     $result = parent::callAction($ctx->get_method(), $ctx->get_parameters());     $ctx->set_result($result);     return $ctx; }  | 
					
_call,就是實際上去呼叫parent::callAction,將原本該有的method name以及parameter傳入後儲存結果
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14  | 
						protected function _post_call(RequestCtx $ctx): ServerResponse|array {     $result = $ctx->get_result();     if ($result instanceof ServerResponse)     {         return $result;     }     $content = $this->_serialize_content(         result: $result,         parsers: $this->_get_serializers()     );     return ['data' => $content]; }  | 
					
_post_call會處理在return前的狀況,這邊處理的內容是,如果controller處理完已經是一個ServerResponse那麼就直接return
如果不是,我們另外將資料序列化做好,放入data中再回傳,確保未來回傳的資料每個method都相同

