diff --git a/KnownIssues-CN.md b/KnownIssues-CN.md index 4e76ecd..c7bae80 100644 --- a/KnownIssues-CN.md +++ b/KnownIssues-CN.md @@ -141,10 +141,15 @@ class TestController extends Controller 'enable' => true, // 启用自动销毁控制器 'excluded_list' => [ //\App\Http\Controllers\TestController::class, // 排除销毁的控制器类列表 + //'App\Http\Controllers\V2\*', // 支持使用通配符的命名空间前缀匹配,该命名空间下的所有控制器都会被排除 ], ], ``` +有两种方式可以排除控制器不被销毁: +1. 精确匹配:指定完整的类名 +2. 前缀匹配:在命名空间末尾使用通配符(*),例如 `App\Http\Controllers\V2\*` 将排除该命名空间下的所有控制器 + ## 不能使用这些函数 - `flush`/`ob_flush`/`ob_end_flush`/`ob_implicit_flush`:`swoole_http_response`不支持`flush`。 diff --git a/KnownIssues.md b/KnownIssues.md index af4d3a3..ca262a2 100644 --- a/KnownIssues.md +++ b/KnownIssues.md @@ -138,10 +138,15 @@ class TestController extends Controller 'enable' => true, // Enable automatic destruction controller 'excluded_list' => [ //\App\Http\Controllers\TestController::class, // The excluded list of destroyed controller classes + //'App\Http\Controllers\V2\*', // Support namespace prefix with wildcard, all controllers under this namespace will be excluded ], ], ``` +There are two ways to exclude controllers from being destroyed: +1. Exact match: specify the full class name +2. Prefix match: use wildcard (*) at the end of namespace, for example `App\Http\Controllers\V2\*` will exclude all controllers under this namespace + ## Cannot call these functions - `flush`/`ob_flush`/`ob_end_flush`/`ob_implicit_flush`: `swoole_http_response` does not support `flush`. diff --git a/src/Illuminate/CleanerManager.php b/src/Illuminate/CleanerManager.php index 391af2c..5c34b43 100644 --- a/src/Illuminate/CleanerManager.php +++ b/src/Illuminate/CleanerManager.php @@ -43,10 +43,16 @@ class CleanerManager /** * White list of controllers to be destroyed - * @var array + * @var array */ protected $whiteListControllers = []; + /** + * White list of controller prefixes to be excluded + * @var array + */ + protected $whiteListPrefixes = []; + /** * @var array */ @@ -152,12 +158,45 @@ public function cleanProviders() /** * Register white list of controllers for cleaning. * - * @param array providers + * @param array $controllers */ protected function registerCleanControllerWhiteList(array $controllers = []) { - $controllers = array_unique($controllers); - $this->whiteListControllers = array_combine($controllers, $controllers); + $this->whiteListControllers = []; + $this->whiteListPrefixes = []; + + foreach ($controllers as $controller) { + if (str_ends_with($controller, '*')) { + $prefix = substr($controller, 0, -1); + $this->whiteListPrefixes[$prefix] = true; // 使用关联数组 + } else { + $this->whiteListControllers[$controller] = true; // 统一使用 true 作为值 + } + } + } + + /** + * Check if controller should be excluded from cleaning + * + * @param string $controllerClass + * @return bool + */ + protected function shouldExcludeController(string $controllerClass): bool + { + // 1. 精确匹配检查(O(1)) + if (isset($this->whiteListControllers[$controllerClass])) { + return true; + } + + // 2. 前缀匹配检查 + // 使用关联数组后,可以优化前缀匹配的性能 + foreach ($this->whiteListPrefixes as $prefix => $_) { + if (strncmp($controllerClass, $prefix, strlen($prefix)) === 0) { + return true; + } + } + + return false; } /** @@ -180,7 +219,7 @@ public function cleanControllers() } if (isset($route->controller)) { // For Laravel 5.4+ - if (empty($this->whiteListControllers) || !isset($this->whiteListControllers[get_class($route->controller)])) { + if (!$this->shouldExcludeController(get_class($route->controller))) { unset($route->controller); } } else { @@ -188,7 +227,8 @@ public function cleanControllers() if ($reflection->hasProperty('controller')) { // Laravel 5.3 $controller = $reflection->getProperty('controller'); $controller->setAccessible(true); - if (empty($this->whiteListControllers) || (($instance = $controller->getValue($route)) && !isset($this->whiteListControllers[get_class($instance)]))) { + $instance = $controller->getValue($route); + if ($instance && !$this->shouldExcludeController(get_class($instance))) { $controller->setValue($route, null); } }