Skip to content

Commit bc9e4da

Browse files
committed
优化控制器扫描机制
1 parent 7a52b0f commit bc9e4da

2 files changed

Lines changed: 65 additions & 8 deletions

File tree

composer.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
],
1111
"require": {
1212
"topthink/framework": "^8.0",
13-
"topthink/think-orm": "^4.0",
14-
"ergebnis/classy": "^1.4"
13+
"topthink/think-orm": "^4.0"
1514
},
1615
"require-dev": {
1716
"topthink/think-ide-helper": "^1.0"

src/InteractsWithRoute.php

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace think\annotation;
44

5-
use Ergebnis\Classy\Constructs;
65
use ReflectionClass;
76
use ReflectionMethod;
87
use think\annotation\route\Group;
@@ -56,7 +55,7 @@ protected function registerAnnotationRoute()
5655
}
5756

5857
if (is_dir($dir)) {
59-
$this->scanDir($dir, $options);
58+
$this->scanDir(realpath($dir), $options);
6059
}
6160
}
6261
});
@@ -66,8 +65,36 @@ protected function registerAnnotationRoute()
6665
protected function scanDir($dir, $options = [])
6766
{
6867
$groups = [];
69-
foreach (Constructs::fromDirectory($dir) as $construct) {
70-
$class = $construct->name();
68+
69+
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(
70+
$dir,
71+
\FilesystemIterator::FOLLOW_SYMLINKS,
72+
));
73+
74+
$namespace = Arr::pull($options, 'namespace') ?: $this->getNamespace($dir, $this->controllerDir, "{$this->app->getNamespace()}\\controller");
75+
76+
if (empty($namespace)) {
77+
return;
78+
}
79+
80+
foreach ($iterator as $fileInfo) {
81+
/** @var \SplFileInfo $fileInfo */
82+
if (!$fileInfo->isFile()) {
83+
continue;
84+
}
85+
86+
if ($fileInfo->getBasename('.php') === $fileInfo->getBasename()) {
87+
continue;
88+
}
89+
90+
$filename = $fileInfo->getRealPath();
91+
92+
$classNamespace = $this->getNamespace(dirname($filename), $dir, $namespace);
93+
if (empty($namespace)) {
94+
continue;
95+
}
96+
97+
$class = "\\{$classNamespace}\\{$fileInfo->getBasename('.php')}";
7198

7299
if (in_array($class, $this->parsedClass)) {
73100
continue;
@@ -81,8 +108,6 @@ protected function scanDir($dir, $options = [])
81108
continue;
82109
}
83110

84-
$filename = $construct->fileNames()[0];
85-
86111
$prefix = $class;
87112

88113
if (Str::startsWith($filename, $this->controllerDir)) {
@@ -180,4 +205,37 @@ protected function scanDir($dir, $options = [])
180205
}
181206
}
182207

208+
/**
209+
* Calculate the namespace based on the relative path between directories
210+
*
211+
* @param string $dir The directory to get the namespace for
212+
* @param string $base The base directory
213+
* @param string $baseNamespace The base namespace
214+
* @return string|null The calculated namespace or null if $dir is not a subdirectory of $base
215+
*/
216+
protected function getNamespace($dir, $base, $baseNamespace)
217+
{
218+
// Normalize directory separators
219+
$dir = rtrim(str_replace('\\', '/', $dir), '/') . '/';
220+
$base = rtrim(str_replace('\\', '/', $base), '/') . '/';
221+
222+
// Check if $dir is a subdirectory of $base
223+
if (!str_starts_with($dir, $base)) {
224+
return null;
225+
}
226+
227+
// Get the relative path
228+
$relativePath = substr($dir, strlen($base));
229+
230+
// If the relative path is empty, return the base namespace
231+
if (empty($relativePath) || $relativePath === '/') {
232+
return $baseNamespace;
233+
}
234+
235+
// Convert directory separators to namespace separators
236+
$namespace = str_replace('/', '\\', rtrim($relativePath, '/'));
237+
238+
// Combine with the base namespace
239+
return $baseNamespace . '\\' . $namespace;
240+
}
183241
}

0 commit comments

Comments
 (0)