您当前的位置: 首页 > 慢生活 > 程序人生 网站首页程序人生
webman-路由-路由自动解析
发布时间:2022-01-19 22:37:30编辑:雪饮阅读()
路由自动解析
当app目录结构非常复杂,webman无法自动解析时,可以利用反射自动配置路由,例如在config/route.php中添加如下代码
$dir_iterator = new \RecursiveDirectoryIterator(app_path());
$iterator = new \RecursiveIteratorIterator($dir_iterator);
foreach ($iterator as $file) {
// 忽略目录和非php文件
if (is_dir($file) || $file->getExtension() != 'php') {
continue;
}
$file_path = str_replace('\\', '/',$file->getPathname());
// 文件路径里不带controller的文件忽略
if (strpos($file_path, 'controller') === false) {
continue;
}
// 根据文件路径计算uri
$uri_path = strtolower(str_replace('controller/', '',substr(substr($file_path, strlen(base_path())), 0, -4)));
// 根据文件路径是被类名
$class_name = str_replace('/', '\\',substr(substr($file_path, strlen(base_path())), 0, -4));
if (!class_exists($class_name)) {
echo "Class $class_name not found, skip route for it\n";
continue;
}
// 通过反射找到这个类的所有共有方法作为action
$class = new ReflectionClass($class_name);
$methods = $class->getMethods(ReflectionMethod::IS_PUBLIC);
$route = function ($uri, $cb) {
//echo "Route $uri [{$cb[0]}, {$cb[1]}]\n";
Route::any($uri, $cb);
Route::any($uri.'/', $cb);
};
// 设置路由
foreach ($methods as $item) {
$action = $item->name;
if (in_array($action, ['__construct', '__destruct'])) {
continue;
}
// action为index时uri里末尾/index可以省略
if ($action === 'index') {
// controller也为index时可以uri里可以省略/index/index
if (substr($uri_path, -6) === '/index') {
$route(substr($uri_path, 0, -6), [$class_name, $action]);
}
$route($uri_path, [$class_name, $action]);
}
$route($uri_path.'/'.$action, [$class_name, $action]);
}
}
通过这个脚本可以自动给app目录下的所有控制器配置路由,让其可以通过url访问。
其实真正的核心部分是:
$methods = $class->getMethods(ReflectionMethod::IS_PUBLIC);
以及其下面的遍历,其它的很容易看懂
关键字词:webman,路由,自动解析