tp6是一個封裝度很高的框架,在大部分場景下都能做到開箱即用
本次遇到情況為,當請求訊息體為索引陣列時,路由引數無法正常獲取
首先看正常路由匹配
路由定義
Route::post('test/:a/:b', 'index/test');
Index控制器輸出引數
public function test($a, $b) { dump($a, $b); }
請求測試,如下圖我們得到了我們所需要的結果
這時將IndexController->test中`$a, $b`引數調換位置(路由不變)
public function test($b, $a) { dump($a, $b); }
這時重新請求,得到的結果依然不變
那麼我們是否可以得到結論:tp6控制器引數會根據路由引數名自動匹配?
看以上結果好像是沒問題,但是有個大坑!
請求體正文中加入陣列內容
路由,控制器輸出方法都不變,僅增加requestBody,得到如下結果
說好的路由匹配呢!
原因說明
在方法中列印出`request->param()`可檢視到剛才的請求最終得到的引數
array:4 [ 0 => 3 1 => 4 "a" => "1" "b" => "2" ]
可以看到訊息體中引數是索引陣列部分,而a b為關聯陣列部分
tp在最終匹配action引數的時候,按照先分配索引,再分配關聯的順序進行了引數傳入,導致沒有得到我們想要的效果
若訊息體內增加鍵值,我們重新嘗試,如下圖依然是我們想要的結果
所以大概得到結論:param()引數的來源為先獲取query、body等引數,再覆蓋上路由引數
解決方案
既然已經知道原因,那麼解決方案就比較好處理了
方案1
更改訊息體,避免直接使用索引陣列傳遞,如
我們在方法內根據鍵值data即可獲取想要的資料
方案2
不需要更改結構體,但action引數不通過傳入引數獲取,由內部自己獲取
// action程式碼如下 public function test() { $a = $this->request->param('a'); $b = $this->request->param('b'); dump($a, $b); dump($this->request->param()); }
使用原訊息體測試
總結
根據結果,不能說這是tp的BUG,可以說這次問題是不熟悉導致,但也算是一個坑吧,在遇到這種情況下確實容易摸不著頭腦
大家專案內使用時多多注意即可~