110 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			110 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * This file is part of webman.
 | |
|  *
 | |
|  * Licensed under The MIT License
 | |
|  * For full copyright and license information, please see the MIT-LICENSE.txt
 | |
|  * Redistributions of files must retain the above copyright notice.
 | |
|  *
 | |
|  * @author    walkor<walkor@workerman.net>
 | |
|  * @copyright walkor<walkor@workerman.net>
 | |
|  * @link      http://www.workerman.net/
 | |
|  * @license   http://www.opensource.org/licenses/mit-license.php MIT License
 | |
|  */
 | |
| 
 | |
| use Webman\Route;
 | |
| 
 | |
| // 已经设置过路由的uri则忽略
 | |
| $routes = Route::getRoutes();
 | |
| $ignore_list = [];
 | |
| foreach ($routes as $tmp_route) {
 | |
|     $ignore_list[$tmp_route->getPath()] = 0;
 | |
| }
 | |
| 
 | |
| $default_app = config('plugin.webman.auto-route.app.default_app');
 | |
| 
 | |
| $suffix = config('app.controller_suffix', '');
 | |
| $suffix_length = strlen($suffix);
 | |
| 
 | |
| // 递归遍历目录查找控制器自动设置路由
 | |
| $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(strtolower($file_path), '/controller/') === false) {
 | |
|         continue;
 | |
|     }
 | |
| 
 | |
|     // 只处理带 controller_suffix 后缀的
 | |
|     if ($suffix_length && substr($file->getBaseName('.php'), -$suffix_length) !== $suffix) {
 | |
|         continue;
 | |
|     }
 | |
| 
 | |
|     // 根据文件路径计算uri
 | |
|     $uri_path = str_replace(['/controller/', '/Controller/'], '/', substr(substr($file_path, strlen(app_path())), 0, - (4 + $suffix_length)));
 | |
| 
 | |
|     // 默认应用
 | |
|     $is_default_app = false;
 | |
|     if (is_string($default_app) && !empty($default_app)) {
 | |
|         $seg = explode('/', $uri_path);
 | |
|         if ($seg[1] == $default_app) {
 | |
|             $uri_path = str_replace($default_app . '/', '', $uri_path);
 | |
|             $is_default_app = true;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // 根据文件路径是被类名
 | |
|     $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);
 | |
|     $class_name = $class->name;
 | |
|     $methods = $class->getMethods(ReflectionMethod::IS_PUBLIC);
 | |
| 
 | |
|     $route = function ($uri, $cb) use ($ignore_list) {
 | |
|         if (isset($ignore_list[strtolower($uri)])) {
 | |
|             return;
 | |
|         }
 | |
|         Route::any($uri, $cb);
 | |
|         if ($uri !== '') {
 | |
|             Route::any($uri . '/', $cb);
 | |
|         }
 | |
|         $lower_uri = strtolower($uri);
 | |
|         if ($lower_uri !== $uri) {
 | |
|             Route::any($lower_uri, $cb);
 | |
|             Route::any($lower_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 (strtolower(substr($uri_path, -6)) === '/index') {
 | |
|                 if ($is_default_app) {
 | |
|                     $route('/', [$class_name, $action]);
 | |
|                 }
 | |
|                 $route(substr($uri_path, 0, -6), [$class_name, $action]);
 | |
|             }
 | |
|             $route($uri_path, [$class_name, $action]);
 | |
|         }
 | |
|         $route($uri_path.'/'.$action, [$class_name, $action]);
 | |
|     }
 | |
| }
 |