This commit is contained in:
2023-12-12 10:56:43 +08:00
parent 5d8bc6d2cf
commit fe8d41ec41
+52 -63
View File
@@ -5,9 +5,10 @@ declare(strict_types=1);
namespace Kiri\Di; namespace Kiri\Di;
use Exception; use Kiri\Di\Inject\Container;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
use Kiri\Di\Inject\Skip; use Kiri\Di\Inject\Skip;
use Psr\Container\ContainerInterface;
use ReflectionException; use ReflectionException;
use ReflectionMethod; use ReflectionMethod;
@@ -15,6 +16,13 @@ class Scanner extends Component
{ {
/**
* @var ContainerInterface
*/
#[Container(ContainerInterface::class)]
public ContainerInterface $container;
/** /**
* @var array * @var array
*/ */
@@ -26,47 +34,21 @@ class Scanner extends Component
* @return void * @return void
* @throws ReflectionException * @throws ReflectionException
*/ */
public function read(string $path): void public function load_directory(string $path): void
{ {
$this->load_dir($path); $dir = new \DirectoryIterator($path);
} $skip = \config('scanner.skip', []);
foreach ($dir as $value) {
if ($value->isDot() || str_starts_with($value->getFilename(), '.')) {
/**
* @param string $namespace
* @return void
* @throws ReflectionException
* @throws Exception
*/
public function parse(string $namespace): void
{
$container = Container::instance();
foreach ($this->files as $file) {
$class = $this->rename($file);
if (!class_exists($class)) {
continue; continue;
} }
$reflect = $container->getReflectionClass($class); if ($value->isDir()) {
if ($reflect->isInstantiable()) { if (in_array($value->getRealPath() . '/', $skip)) {
$data = $reflect->getAttributes(Skip::class);
if (count($data) > 0) {
continue; continue;
} }
$object = $container->parse($class); $this->load_directory($value->getRealPath());
} else if ($value->getExtension() == 'php') {
$methods = $container->getReflectionClass($class); $this->load_file($value->getRealPath());
foreach ($methods->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
if ($method->isStatic() || $method->getDeclaringClass()->getName() != $class) {
continue;
}
$attributes = $method->getAttributes();
foreach ($attributes as $attribute) {
if (!class_exists($attribute->getName())) {
continue;
}
$attribute->newInstance()->dispatch($object, $method->getName());
}
}
} }
} }
} }
@@ -88,31 +70,6 @@ class Scanner extends Component
} }
/**
* @param string $path
* @return void
* @throws ReflectionException
*/
private function load_dir(string $path): void
{
$dir = new \DirectoryIterator($path);
$skip = \config('scanner.skip', []);
foreach ($dir as $value) {
if ($value->isDot() || str_starts_with($value->getFilename(), '.')) {
continue;
}
if ($value->isDir()) {
if (in_array($value->getRealPath() . '/', $skip)) {
continue;
}
$this->load_dir($value->getRealPath());
} else if ($value->getExtension() == 'php') {
$this->load_file($value->getRealPath());
}
}
}
/** /**
* @param string $path * @param string $path
* @return void * @return void
@@ -124,11 +81,43 @@ class Scanner extends Component
require_once "$path"; require_once "$path";
$path = str_replace($_SERVER['PWD'], '', $path); $path = str_replace($_SERVER['PWD'], '', $path);
$path = str_replace('.php', '', $path); $path = str_replace('.php', '', $path);
$this->files[] = $path; $this->parseFile($path);
} catch (\Throwable $throwable) { } catch (\Throwable $throwable) {
error($throwable); error($throwable);
} }
} }
/**
* @param $file
* @return void
* @throws ReflectionException
*/
protected function parseFile($file): void
{
$class = $this->rename($file);
if (class_exists($class)) {
$reflect = $this->container->getReflectionClass($class);
if ($reflect->isInstantiable()) {
$data = $reflect->getAttributes(Skip::class);
if (count($data) > 0) {
return;
}
$object = $this->container->parse($class);
$methods = $this->container->getReflectionClass($class);
foreach ($methods->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
if ($method->isStatic() || $method->getDeclaringClass()->getName() != $class) {
continue;
}
$attributes = $method->getAttributes();
foreach ($attributes as $attribute) {
if (!class_exists($attribute->getName())) {
continue;
}
$attribute->newInstance()->dispatch($object, $method->getName());
}
}
}
}
}
} }