2024-05-20 11:51:07 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Core;
|
|
|
|
|
|
|
|
use DI\ContainerBuilder;
|
|
|
|
use Doctrine\Common\Annotations\AnnotationReader;
|
2024-05-21 14:33:56 +08:00
|
|
|
use Doctrine\Common\Annotations\AnnotationRegistry;
|
2024-05-20 11:51:07 +08:00
|
|
|
class BeanFactory
|
|
|
|
{
|
|
|
|
|
|
|
|
//配置文件
|
|
|
|
private static $env = [];
|
|
|
|
//IOC容器
|
|
|
|
private static $container;
|
|
|
|
private static $handlers = [];
|
|
|
|
|
|
|
|
//初始化函数
|
2024-06-26 17:13:45 +08:00
|
|
|
public static function init($bool = false)
|
2024-05-20 11:51:07 +08:00
|
|
|
{
|
|
|
|
self::$env = parse_ini_file(ROOT_PATH . "/.env");
|
|
|
|
//初始容器Builder
|
|
|
|
$builder = new ContainerBuilder();
|
|
|
|
//启用注释 主要是用它的Inject注释
|
2024-05-31 14:57:01 +08:00
|
|
|
$builder->useAttributes(false);
|
2024-05-20 11:51:07 +08:00
|
|
|
//容器初始化
|
|
|
|
self::$container = $builder->build();
|
|
|
|
$handlers = glob(ROOT_PATH . "/core/annotationhandlers/*.php");
|
|
|
|
foreach ($handlers as $handler) {
|
|
|
|
self::$handlers = array_merge(self::$handlers, require_once($handler));
|
|
|
|
}
|
2024-05-21 14:33:56 +08:00
|
|
|
|
2024-05-20 11:51:07 +08:00
|
|
|
//扫描(重点)
|
|
|
|
$scans = [
|
|
|
|
//必须扫描的文件夹
|
|
|
|
ROOT_PATH . "/core/init" => "Core\\",
|
|
|
|
//用户配置的扫描路径
|
|
|
|
self::_getEnv("scan_dir", ROOT_PATH . "/app") => self::_getEnv("scan_root_namespace", "APP\\")
|
|
|
|
];
|
|
|
|
//$scanDir = self::_getEnv("scan_dir",ROOT_PATH."/app");
|
|
|
|
//$scanRootNamespace = self::_getEnv("scan_root_namespace","APP\\");
|
|
|
|
foreach ($scans as $scanDir => $scanRootNamespace) {
|
|
|
|
self::ScanBeans($scanDir, $scanRootNamespace);
|
|
|
|
}
|
|
|
|
//self::ScanBeans();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private static function getAllBeanFiles($dir)
|
|
|
|
{
|
|
|
|
$ret = [];
|
|
|
|
$files = glob($dir . "/*");
|
|
|
|
foreach ($files as $file) {
|
|
|
|
if (is_dir($file)) {
|
|
|
|
//递归合并,防止数组变成嵌套数组
|
|
|
|
$ret = array_merge($ret, self::getAllBeanFiles($file));
|
|
|
|
} elseif (pathinfo($file)["extension"] == "php") {
|
|
|
|
$ret[] = $file;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
//获取env文件的配置内容
|
|
|
|
private static function _getEnv(string $key, string $default = '')
|
|
|
|
{
|
|
|
|
if (isset(self::$env[$key]))
|
|
|
|
return self::$env[$key];
|
|
|
|
return $default;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function ScanBeans($scanDir, $scanRootNamespace)
|
|
|
|
{
|
|
|
|
//$files = glob($scanDir."/*.php");
|
|
|
|
$files = self::getAllBeanFiles($scanDir);
|
|
|
|
foreach ($files as $file) {
|
|
|
|
require_once $file;
|
|
|
|
}
|
|
|
|
//注释类对象
|
|
|
|
|
|
|
|
$reader = new AnnotationReader();
|
|
|
|
//get_declared_classes返回由已定义类的名字所组成的数组
|
|
|
|
foreach (get_declared_classes() as $class) {
|
|
|
|
if (strstr($class, $scanRootNamespace)) {
|
|
|
|
$refClass = new \ReflectionClass($class);
|
2024-05-21 14:33:56 +08:00
|
|
|
//AnnotationRegistry::loadAnnotationClass($class);
|
2024-05-20 11:51:07 +08:00
|
|
|
//获取所有类的注释
|
|
|
|
$classAnnos = $reader->getClassAnnotations($refClass);
|
2024-05-31 14:57:01 +08:00
|
|
|
if ($refClass->getName() == 'Core\server\HttpServer') {
|
|
|
|
continue;
|
|
|
|
}
|
2024-05-20 11:51:07 +08:00
|
|
|
$instance = self::$container->get($refClass->getName());
|
|
|
|
foreach ($classAnnos as $classAnno) {
|
|
|
|
//根据注释的类型获取对应处理方法
|
|
|
|
$hander = self::$handlers[get_class($classAnno)];
|
|
|
|
//$hander($instance, self::$container);
|
|
|
|
|
|
|
|
self::handlerPropAnno($instance,$refClass,$reader);
|
|
|
|
//处理方法注解
|
|
|
|
self::handlerMethodAnno($instance,$refClass,$reader);
|
|
|
|
|
|
|
|
//处理类注解
|
|
|
|
$hander($instance,self::$container,$classAnno);
|
|
|
|
}
|
|
|
|
//self::handlerMethodAnno($instance, $refClass, $reader);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static function getBean($name)
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
return self::$container->get($name);
|
|
|
|
} catch (\Exception $exception) {
|
|
|
|
return false;//没有找到直接返回false
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function setBean($name, $value)
|
|
|
|
{
|
|
|
|
return self::$container->set($name, $value);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static function handlerPropAnno(&$instance, \ReflectionClass $refClass, AnnotationReader $reader)
|
|
|
|
{
|
2024-06-26 17:13:45 +08:00
|
|
|
//var_dump($refClass->getName());
|
2024-05-20 11:51:07 +08:00
|
|
|
//读取反射对象的属性
|
|
|
|
$props = $refClass->getProperties();
|
|
|
|
foreach ($props as $prop) {
|
|
|
|
//$prop必须是反射对象属性
|
|
|
|
$propAnnos = $reader->getPropertyAnnotations($prop);
|
|
|
|
foreach ($propAnnos as $propAnno) {
|
|
|
|
//返回对象实例 obj 所属类的名字。如果 obj 不是一个对象则返回 FALSE
|
|
|
|
$handler = self::$handlers[get_class($propAnno)];
|
|
|
|
$handler($prop, $instance, $propAnno);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 处理方法注解
|
|
|
|
* @param $instance
|
|
|
|
* @param \ReflectionClass $refClass
|
|
|
|
* @param \Doctrine\Common\Annotations\AnnotationReader $reader
|
|
|
|
*/
|
|
|
|
private static function handlerMethodAnno(&$instance, \ReflectionClass $refClass, AnnotationReader $reader)
|
|
|
|
{
|
|
|
|
//读取反射对象的属性
|
|
|
|
$methods = $refClass->getMethods();//取出所有的方法
|
|
|
|
foreach ($methods as $method) {
|
|
|
|
//$prop必须是反射对象属性
|
|
|
|
$methodAnnos = $reader->getMethodAnnotations($method);
|
|
|
|
foreach ($methodAnnos as $methodAnno) {
|
|
|
|
//返回对象实例 obj 所属类的名字。如果 obj 不是一个对象则返回 FALSE
|
|
|
|
$handler = self::$handlers[get_class($methodAnno)];
|
|
|
|
$handler($method, $instance, $methodAnno);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|