僅支持`PATHINFO`模式的 URL 解析,且與控制器名稱(方法)保持一致,控制器搜索規則為優先完整匹配模式
在沒有路由干預的情況下,內置的解析規則支持無限級嵌套目錄,如下方兩個例子所示
* [http://serverName/api/auth/login](http://servername/api/auth/login)
對應執行的方法為 \\App\\HttpController\\Api\\Auth::login()
* [http://serverName/a/b/c/d/f](http://servername/a/b/c/d/f)
* 如果 f 為控制器名,則執行的方法為 \\App\\HttpController\\A\\B\\C\\D\\F::index()
* 如果 f 為方法名,則執行的方法為 \\App\\HttpControllers\\A\\B\\C\\D::f()
* 如果最后的路徑為`index`時,底層會自動忽略,并直接調用控制器的默認方法(也就是index)
實現代碼:
~~~php
//如果請求為/Index/index,或/abc/index
//將自動刪除最后面的index字符,$path已經被處理為/Index或/abc
$pathInfo = ltrim($path,"/");
$list = explode("/",$pathInfo);
$actionName = null;
$finalClass = null;
$controlMaxDepth = $this->maxDepth;
$currentDepth = count($list);
$maxDepth = $currentDepth < $controlMaxDepth ? $currentDepth : $controlMaxDepth;
while ($maxDepth >= 0){//解析層級
$className = '';
//根據請求的路徑,逐層解析字符串轉為首字母大寫,并判斷字符串是否有效,無效則默認為Index
for ($i=0 ;$i<$maxDepth;$i++){
$className = $className."\\".ucfirst($list[$i] ?: 'Index');//為一級控制器Index服務
}
//如果找到了該控制器,則退出循環
if(class_exists($this->controllerNameSpacePrefix.$className)){
//嘗試獲取該class后的actionName
$actionName = empty($list[$i]) ? 'index' : $list[$i];
$finalClass = $this->controllerNameSpacePrefix.$className;
break;
}else{
//嘗試搜搜index控制器
$temp = $className."\\Index";
if(class_exists($this->controllerNameSpacePrefix.$temp)){
$finalClass = $this->controllerNameSpacePrefix.$temp;
//嘗試獲取該class后的actionName
$actionName = empty($list[$i]) ? 'index' : $list[$i];
break;
}
}
$maxDepth--;
}
~~~