This commit is contained in:
2023-04-16 16:40:44 +08:00
parent 728a2dd560
commit 8cde1f32ac
2 changed files with 117 additions and 5 deletions
+14 -5
View File
@@ -72,6 +72,7 @@ class Container implements ContainerInterface
* @param string $id
* @return mixed
* @throws ReflectionException
* @throws \Exception
*/
public function get(string $id): mixed
{
@@ -83,6 +84,9 @@ class Container implements ContainerInterface
$id = $this->_interfaces[$id];
}
$this->_singletons[$id] = $this->make($id);
if (!$this->_singletons[$id]) {
throw new \Exception('Class that cannot be instantiated。');
}
}
return $this->_singletons[$id];
}
@@ -126,16 +130,19 @@ class Container implements ContainerInterface
/**
* @param string $className
* @return ReflectionClass
* @return ReflectionClass|null
* @throws ReflectionException
*/
public function getReflectionClass(string $className): ReflectionClass
public function getReflectionClass(string $className): ?ReflectionClass
{
if (isset($this->_reflection[$className])) {
return $this->_reflection[$className];
}
$class = new ReflectionClass($className);
if (!$class->isInstantiable()) {
return null;
}
return $this->_reflection[$className] = $class;
}
@@ -145,12 +152,14 @@ class Container implements ContainerInterface
* @param string $className
* @param array $construct
* @param array $config
* @return object
* @return object|null
* @throws ReflectionException
*/
public function make(string $className, array $construct = [], array $config = []): object
public function make(string $className, array $construct = [], array $config = []): ?object
{
$reflect = $this->getReflectionClass($className);
if (($reflect = $this->getReflectionClass($className)) === null) {
return null;
}
$constructorHandler = $reflect->getConstructor();
if (count($construct) < 1 && $constructorHandler !== null) {
+103
View File
@@ -0,0 +1,103 @@
<?php
declare(strict_types=1);
namespace Kiri\Di;
use Exception;
use Kiri\Abstracts\Component;
use ReflectionException;
class Scanner extends Component
{
private array $files = [];
/**
* @param string $path
* @return void
*/
public function read(string $path): void
{
$this->load_dir($path);
}
/**
* @param string $namespace
* @return void
* @throws ReflectionException
* @throws Exception
*/
public function parse(string $namespace): void
{
$container = Container::instance();
foreach ($this->files as $file) {
$class = $namespace . '\\' . $this->rename($file);
if (file_exists($class)) {
error('Please follow the PSR-4 specification to write code.' . $class);
continue;
}
$container->parse($class);
}
}
/**
* @param string $file
* @return string
*/
private function rename(string $file): string
{
$filter = array_filter(explode('/', $file), function ($value) {
if (empty($value)) {
return false;
}
return ucfirst($value);
});
array_shift($filter);
return implode('\\', $filter);
}
/**
* @param string $path
* @return void
*/
private function load_dir(string $path): void
{
$dir = new \DirectoryIterator($path);
foreach ($dir as $value) {
if ($value->isDot()) {
continue;
}
if ($value->isDir()) {
$this->load_dir($value->getRealPath());
} else if ($value->getExtension() == '.php') {
$this->load_file($value);
}
}
}
/**
* @param string $path
* @return void
*/
private function load_file(string $path): void
{
try {
require_once "$path";
$path = str_replace($_SERVER['HOME'], '', $path);
$path = str_replace('.php', '', $path);
$this->files[] = $path;
} catch (\Throwable $throwable) {
error($throwable->getMessage(), [$throwable]);
}
}
}