From 1a4a63a43f12bd295c87ef8e76f7558cccc91feb Mon Sep 17 00:00:00 2001 From: Shine Date: Tue, 17 Jun 2025 19:14:35 +0800 Subject: [PATCH 1/2] Added support for excluding clean controllers using namespace prefixes. - Add support for excluding controllers by namespace prefix using wildcard (*) - Add new property `$whiteListPrefixes` to store prefix patterns - Add new method `shouldExcludeController` to handle both exact and prefix matches Example: 'App\Http\Controllers\V2\*' will exclude all controllers under V2 namespace --- src/Illuminate/CleanerManager.php | 52 +++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 6 deletions(-) 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); } } From 616b290f62b022f17bc9ec380f6770abe00d4058 Mon Sep 17 00:00:00 2001 From: Shine Date: Tue, 17 Jun 2025 19:15:11 +0800 Subject: [PATCH 2/2] Updated the documentation to add two ways to exclude controllers: exact match and prefix match, and support for wildcards (*). --- KnownIssues-CN.md | 5 +++++ KnownIssues.md | 5 +++++ 2 files changed, 10 insertions(+) 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`.