From b5e0026816147ac6710b4f0006b74486ac64dbd2 Mon Sep 17 00:00:00 2001 From: whwyy Date: Wed, 24 Jun 2026 20:45:37 +0800 Subject: [PATCH] eee --- src/Router.php | 64 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/src/Router.php b/src/Router.php index 89074b1..c97e638 100644 --- a/src/Router.php +++ b/src/Router.php @@ -215,11 +215,12 @@ class Router $changedFiles = $container->get(HotReloadState::class)->consume(); // Worker 首次启动(无变更文件 + Master 已完成扫描): - // RouterCollector 已由 Master 填充(含路由文件路由 + 注解路由),Worker 通过 fork 继承 - // 重新 include 路由文件以更新 Router::get/post 等显式注册的路由(同 key 覆盖不产生重复) - // 注解路由(#[Route]/#[Get]/#[Post]等)由 Master 注入保留,无需重新扫描 app 目录 + // 重新 include 路由文件(Router::get/post 显式注册) + 基于 Master 扫描清单重建注解路由 + // 避免 opcache_compile_file,仅用 Reflection 重建路由,内存开销极小 if (empty($changedFiles) && self::$initialScanDone) { + $container->get(DataGrip::class)->reset(static::$type); $this->read_dir_file(APP_PATH . 'routes'); + $this->rebuildAnnotationRoutes($container); $this->reset($container); $coordinator->done(); return; @@ -294,6 +295,63 @@ class Router } + /** + * 基于 Master 扫描清单重建注解路由(轻量级,无文件 I/O) + * 遍历 Scanner manifest 中的所有类,用 Reflection 重新发现 #[Route]/#[Get] 等注解 + * 避免 Worker 重复执行 opcache_compile_file,但确保注解路由不丢失 + * + * @param ContainerInterface $container + * @return void + */ + private function rebuildAnnotationRoutes(ContainerInterface $container): void + { + $scanner = $container->get(Kiri\Di\Scanner::class); + $scanConfig = array_merge( + config('servers.reload.scan', []), + config('site.scanner', []) + ); + $scanner->setConfig($scanConfig); + + // 获取 Master 扫描产生的完整清单,遍历所有已注册类重建注解路由 + $manifestEntries = $scanner->getManifestClasses(); + foreach ($manifestEntries as $path => $entry) { + $classes = is_array($entry) && isset($entry['classes']) ? $entry['classes'] : []; + foreach ($classes as $class) { + if (!class_exists($class)) { + continue; + } + try { + $reflect = $container->getReflectionClass($class); + if (!$reflect->isInstantiable() || $reflect->isTrait() || $reflect->isEnum() || $reflect->isInterface()) { + continue; + } + foreach ($reflect->getMethods() as $method) { + if ($method->isStatic() || $method->getDeclaringClass()->getName() !== $class) { + continue; + } + foreach ($method->getAttributes() as $attribute) { + $attrName = $attribute->getName(); + if (!class_exists($attrName)) { + continue; + } + try { + $instance = $attribute->newInstance(); + if ($instance instanceof Kiri\Di\Interface\InjectMethodInterface) { + $instance->dispatch($class, $method->getName()); + } + } catch (\Throwable $e) { + \Kiri::getLogger()->error("AnnotationRoute rebuild [{$class}::{$method->getName()}]: " . $e->getMessage()); + } + } + } + } catch (\Throwable $e) { + \Kiri::getLogger()->error("AnnotationRoute class [{$class}]: " . $e->getMessage()); + } + } + } + } + + /** * @param $path *