问题:为什么要实现这个功能?
答:因为在写接口文档的时候,发现了如下图所示:
有轻度强迫症的我,迫切想把这一坨控制器放到一起,然后命名为C2c。
于是,就有了这篇博客。
PS:TP3并未原生支持一二级自动匹配控制器,而考虑到不影响原有的接口,所以才有这样的需求。
思路是:设置默认控制器层级为2,然后写代码简单实现兼容原先的一级。
实现如下:
PS:可能不是很优雅,目前暂时还未发现有问题,如果有问题,欢迎留言补充,或者我遇到问题会来更新这篇博文。
1、找到\ThinkPHP\Library\Think\Dispatcher.class.php,修改如下代码
private static function getController(&$paths, $urlCase)
{
...
if ($paths) {
/*
* 此处修改为2级内自适应 by lee 20190214
* 先判断是否存在控制器
*/
$old_paths=$paths;
// PATH_INFO检测标签位
Hook::listen('path_info');
if (C('CONTROLLER_LEVEL') > 1) {// 控制器层次
$controller = implode('/', array_slice($paths, 0, C('CONTROLLER_LEVEL')));
$paths = array_slice($paths, C('CONTROLLER_LEVEL'));
} else {
$controller = array_shift($paths);
}
}
...
if ($urlCase) {
// URL地址不区分大小写
// 智能识别方式 user_type 识别到 UserTypeController 控制器
$controller = parse_name($controller, 1);
}
$controller=strip_tags(ucfirst($controller));
//此处,查询控制器是否存在,如果不存在则去掉/后面 判断是否是文件夹,如果不是则去掉第一级
//切割控制器
if(strpos($controller,'/')!==false){
$controller_arr=explode('/',$controller);
$controller_dir=$controller_arr[0];
$root_path=realpath(__ROOT__);
$module_path=str_replace('.','',MODULE_PATH);
$controller_path=$root_path.$module_path.'Controller/'.$controller_dir;
//此处根据路径参数数量判断是否进入目录检测
//如果目录存在 则检查控制器是否存在
if(is_dir($controller_path)===true){
$controller_name=ucfirst($controller_arr[1]); //此处应优化未按照实际大小写的控制器名
$controller_file=$controller_path.'/'.$controller_name.'Controller.class.php';
if(file_exists($controller_file)==false){
$controller=$controller_arr[0];
//补回一个参数
$paths = array_slice($old_paths, (C('CONTROLLER_LEVEL')-1));
}
}else{
$controller=$controller_arr[0];
//补回一个参数
$paths = array_slice($old_paths, (C('CONTROLLER_LEVEL')-1));
}
}
return $controller;
}
这样子,就可以实现预期效果了。