diff --git a/bin/phpunit-zm b/bin/phpunit-zm
index 64b01667..6346a1b4 100755
--- a/bin/phpunit-zm
+++ b/bin/phpunit-zm
@@ -57,14 +57,12 @@ $options['driver'] = 'workerman';
$options['worker-num'] = 1;
$options['private-mode'] = true;
-$kernel = \ZM\Kernel::getInstance();
-$kernel->setEnvironment('development');
-$kernel->setTestMode(true);
-$kernel->setConfigDir(dirname(__DIR__) . '/config');
-$kernel->bootstrap();
-
try {
- (new Framework($options))->init()->start();
+ $framework = (new Framework($options));
+ $framework->setEnvironment('development');
+ $framework->setConfigDir(dirname(__DIR__) . '/config');
+ $framework->bootstrap();
+ $framework->init()->start();
exit($_swoole_atomic->get());
} catch (Throwable $e) {
echo $e->getMessage() . PHP_EOL;
diff --git a/config/container.php b/config/container.php
index 099d2337..c858cb47 100644
--- a/config/container.php
+++ b/config/container.php
@@ -8,7 +8,7 @@ use Psr\Log\LoggerInterface;
use ZM\Config\Environment;
use ZM\Config\EnvironmentInterface;
use ZM\Framework;
-use ZM\Kernel;
+use ZM\HasRuntimeInfo;
/*
* 这里是容器的配置文件,你可以在这里配置容器的绑定和其他一些参数。
@@ -28,6 +28,8 @@ return [
Driver::class => fn () => Framework::getInstance()->getDriver(),
LoggerInterface::class => fn () => logger(),
EnvironmentInterface::class => Environment::class,
+
+ HasRuntimeInfo::class => Framework::class,
],
// 容器的缓存配置,默认情况下,只有在生产环境下才会启用缓存
@@ -37,7 +39,7 @@ return [
// 详细介绍请参阅:https://php-di.org/doc/performances.html#caching
'cache' => [
// 是否启用缓存,支持 bool、callable
- 'enable' => fn () => Kernel::getInstance()->environment('production'),
+ 'enable' => fn () => Framework::getInstance()->environment('production'),
'namespace' => 'zm',
],
];
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 7f81ee24..1ceb3339 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -28,6 +28,6 @@
-
+
diff --git a/src/ZM/Bootstrap/Bootstrapper.php b/src/ZM/Bootstrap/Bootstrapper.php
index a258d2dd..e5c32876 100644
--- a/src/ZM/Bootstrap/Bootstrapper.php
+++ b/src/ZM/Bootstrap/Bootstrapper.php
@@ -4,9 +4,9 @@ declare(strict_types=1);
namespace ZM\Bootstrap;
-use ZM\Kernel;
+use ZM\HasRuntimeInfo;
interface Bootstrapper
{
- public function bootstrap(Kernel $kernel): void;
+ public function bootstrap(HasRuntimeInfo $runtime_info): void;
}
diff --git a/src/ZM/Bootstrap/HandleExceptions.php b/src/ZM/Bootstrap/HandleExceptions.php
index 2f6734e0..f873a7ca 100644
--- a/src/ZM/Bootstrap/HandleExceptions.php
+++ b/src/ZM/Bootstrap/HandleExceptions.php
@@ -6,11 +6,11 @@ namespace ZM\Bootstrap;
use OneBot\Exception\ExceptionHandler;
use ZM\Exception\Handler;
-use ZM\Kernel;
+use ZM\HasRuntimeInfo;
class HandleExceptions implements Bootstrapper
{
- public function bootstrap(Kernel $kernel): void
+ public function bootstrap(HasRuntimeInfo $runtime_info): void
{
// 注册全局错误处理器
set_error_handler(function ($error_no, $error_msg, $error_file, $error_line) {
diff --git a/src/ZM/Bootstrap/LoadConfiguration.php b/src/ZM/Bootstrap/LoadConfiguration.php
index bf1db263..98983505 100644
--- a/src/ZM/Bootstrap/LoadConfiguration.php
+++ b/src/ZM/Bootstrap/LoadConfiguration.php
@@ -8,11 +8,11 @@ use Dotenv\Dotenv;
use ZM\Config\Environment;
use ZM\Config\EnvironmentInterface;
use ZM\Config\ZMConfig;
-use ZM\Kernel;
+use ZM\HasRuntimeInfo;
class LoadConfiguration implements Bootstrapper
{
- public function bootstrap(Kernel $kernel): void
+ public function bootstrap(HasRuntimeInfo $runtime_info): void
{
// TODO: 重新思考容器绑定的加载方式,从而在此处使用 interface
$env = resolve(Environment::class);
@@ -20,7 +20,7 @@ class LoadConfiguration implements Bootstrapper
new ZMConfig([
'source' => [
- 'paths' => [$kernel->getConfigDir()],
+ 'paths' => [$runtime_info->getConfigDir()],
],
]);
}
diff --git a/src/ZM/Bootstrap/LoadGlobalDefines.php b/src/ZM/Bootstrap/LoadGlobalDefines.php
index e06f671b..4152f43b 100644
--- a/src/ZM/Bootstrap/LoadGlobalDefines.php
+++ b/src/ZM/Bootstrap/LoadGlobalDefines.php
@@ -4,11 +4,11 @@ declare(strict_types=1);
namespace ZM\Bootstrap;
-use ZM\Kernel;
+use ZM\HasRuntimeInfo;
class LoadGlobalDefines implements Bootstrapper
{
- public function bootstrap(Kernel $kernel): void
+ public function bootstrap(HasRuntimeInfo $runtime_info): void
{
require FRAMEWORK_ROOT_DIR . '/src/Globals/global_defines_framework.php';
}
diff --git a/src/ZM/Bootstrap/LoadPlugins.php b/src/ZM/Bootstrap/LoadPlugins.php
index d531d4eb..d469e867 100644
--- a/src/ZM/Bootstrap/LoadPlugins.php
+++ b/src/ZM/Bootstrap/LoadPlugins.php
@@ -4,12 +4,12 @@ declare(strict_types=1);
namespace ZM\Bootstrap;
-use ZM\Kernel;
+use ZM\HasRuntimeInfo;
use ZM\Plugin\PluginManager;
class LoadPlugins implements Bootstrapper
{
- public function bootstrap(Kernel $kernel): void
+ public function bootstrap(HasRuntimeInfo $runtime_info): void
{
// 先遍历下插件目录下是否有这个插件,没有这个插件则不能打包
$plugin_dir = config('global.plugin.load_dir', SOURCE_ROOT_DIR . '/plugins');
diff --git a/src/ZM/Bootstrap/RegisterEventProvider.php b/src/ZM/Bootstrap/RegisterEventProvider.php
index 9976499a..1b50bd7c 100644
--- a/src/ZM/Bootstrap/RegisterEventProvider.php
+++ b/src/ZM/Bootstrap/RegisterEventProvider.php
@@ -5,11 +5,11 @@ declare(strict_types=1);
namespace ZM\Bootstrap;
use ZM\Event\EventProvider;
-use ZM\Kernel;
+use ZM\HasRuntimeInfo;
class RegisterEventProvider implements Bootstrapper
{
- public function bootstrap(Kernel $kernel): void
+ public function bootstrap(HasRuntimeInfo $runtime_info): void
{
global $ob_event_provider;
$ob_event_provider = EventProvider::getInstance();
diff --git a/src/ZM/Bootstrap/RegisterLogger.php b/src/ZM/Bootstrap/RegisterLogger.php
index 6d57fad2..3451e31c 100644
--- a/src/ZM/Bootstrap/RegisterLogger.php
+++ b/src/ZM/Bootstrap/RegisterLogger.php
@@ -4,17 +4,17 @@ declare(strict_types=1);
namespace ZM\Bootstrap;
-use ZM\Kernel;
+use ZM\HasRuntimeInfo;
use ZM\Logger\ConsoleLogger;
class RegisterLogger implements Bootstrapper
{
- public function bootstrap(Kernel $kernel): void
+ public function bootstrap(HasRuntimeInfo $runtime_info): void
{
// 初始化 Logger
if (!ob_logger_registered()) {
// 如果没有注册过 Logger,那么就初始化一个,在启动框架前注册的话,就不会初始化了,可替换为其他 Logger
- $logger = new ConsoleLogger($kernel->getLogLevel());
+ $logger = new ConsoleLogger($runtime_info->getLogLevel());
ob_logger_register($logger);
}
}
diff --git a/src/ZM/Bootstrap/SetInternalTimezone.php b/src/ZM/Bootstrap/SetInternalTimezone.php
index f03d1a20..f9bea253 100644
--- a/src/ZM/Bootstrap/SetInternalTimezone.php
+++ b/src/ZM/Bootstrap/SetInternalTimezone.php
@@ -4,11 +4,11 @@ declare(strict_types=1);
namespace ZM\Bootstrap;
-use ZM\Kernel;
+use ZM\HasRuntimeInfo;
class SetInternalTimezone implements Bootstrapper
{
- public function bootstrap(Kernel $kernel): void
+ public function bootstrap(HasRuntimeInfo $runtime_info): void
{
date_default_timezone_set(config('global.runtime.timezone', 'UTC'));
}
diff --git a/src/ZM/Command/Server/ServerStartCommand.php b/src/ZM/Command/Server/ServerStartCommand.php
index 1e830448..4980678d 100644
--- a/src/ZM/Command/Server/ServerStartCommand.php
+++ b/src/ZM/Command/Server/ServerStartCommand.php
@@ -74,7 +74,7 @@ class ServerStartCommand extends ServerCommand
}
// 框架启动的入口
- (new Framework($input->getOptions()))->init()->start();
+ Framework::getInstance()->init($input->getOptions())->start();
return 0;
}
}
diff --git a/src/ZM/Config/ZMConfig.php b/src/ZM/Config/ZMConfig.php
index 1c6d8fdc..319e389b 100644
--- a/src/ZM/Config/ZMConfig.php
+++ b/src/ZM/Config/ZMConfig.php
@@ -8,7 +8,7 @@ use OneBot\Config\Config;
use OneBot\Config\Loader\LoaderInterface;
use OneBot\Util\Singleton;
use ZM\Exception\ConfigException;
-use ZM\Kernel;
+use ZM\Framework;
class ZMConfig
{
@@ -302,7 +302,7 @@ class ZMConfig
}
if ($type === 'environment') {
$name_and_env = explode('.', $name);
- if (Kernel::getInstance()->environment($name_and_env[1])) {
+ if (Framework::getInstance()->environment($name_and_env[1])) {
return true;
}
}
diff --git a/src/ZM/ConsoleApplication.php b/src/ZM/ConsoleApplication.php
index 42839559..1d1d804e 100644
--- a/src/ZM/ConsoleApplication.php
+++ b/src/ZM/ConsoleApplication.php
@@ -52,8 +52,8 @@ final class ConsoleApplication extends Application
$input = $event->getInput();
// 初始化内核
- /** @var Kernel $kernel */
- $kernel = Kernel::getInstance();
+ /** @var Framework $kernel */
+ $kernel = Framework::getInstance();
$kernel->setConfigDir($input->getOption('config-dir'));
$kernel->setEnvironment($input->getOption('env'));
$kernel->setDebugMode($input->getOption('debug'));
diff --git a/src/ZM/Container/ContainerHolder.php b/src/ZM/Container/ContainerHolder.php
index a99abb83..41022b6a 100644
--- a/src/ZM/Container/ContainerHolder.php
+++ b/src/ZM/Container/ContainerHolder.php
@@ -8,7 +8,7 @@ use DI;
use DI\Container;
use DI\ContainerBuilder;
use OneBot\Driver\Coroutine\Adaptive;
-use ZM\Kernel;
+use ZM\Framework;
class ContainerHolder
{
@@ -66,6 +66,6 @@ class ContainerHolder
if (self::$config) {
return;
}
- self::$config = require Kernel::getInstance()->getConfigDir() . '/container.php';
+ self::$config = require Framework::getInstance()->getConfigDir() . '/container.php';
}
}
diff --git a/src/ZM/Framework.php b/src/ZM/Framework.php
index 40fb6381..7758c31c 100644
--- a/src/ZM/Framework.php
+++ b/src/ZM/Framework.php
@@ -20,6 +20,7 @@ use OneBot\Driver\Swoole\SwooleDriver;
use OneBot\Driver\Workerman\Worker;
use OneBot\Driver\Workerman\WorkermanDriver;
use OneBot\Util\Singleton;
+use ZM\Bootstrap\Bootstrapper;
use ZM\Command\Server\ServerStartCommand;
use ZM\Container\ContainerBindingListener;
use ZM\Event\Listener\HttpEventListener;
@@ -38,7 +39,7 @@ use ZM\Utils\EasterEgg;
* 框架入口类
* @since 3.0
*/
-class Framework
+class Framework implements HasRuntimeInfo
{
use Singleton;
@@ -67,31 +68,40 @@ class Framework
Bootstrap\SetInternalTimezone::class, // 设置时区
];
+ protected string $environment = 'development';
+
+ protected bool $debug_mode = false;
+
+ protected string $log_level = 'info';
+
+ protected string $config_dir = SOURCE_ROOT_DIR . '/config';
+
/**
* 框架初始化文件
- *
- * @param array $argv 传入的参数(见 ServerStartCommand)
* @throws \Exception
*/
- public function __construct(array $argv = [])
+ public function __construct()
{
// 单例化整个Framework类
if (self::$instance !== null) {
throw new SingletonViolationException(self::class);
}
self::$instance = $this;
-
- // 初始化必需的args参数,如果没有传入的话,使用默认值
- $this->argv = empty($argv) ? ServerStartCommand::exportOptionArray() : $argv;
}
/**
* 初始化框架
*
+ * @param array $argv 传入的参数(见 ServerStartCommand)
+ *
* @throws \Exception
*/
- public function init(): Framework
+ public function init(array $argv = []): Framework
{
+ // TODO: discard argv
+ // 初始化必需的args参数,如果没有传入的话,使用默认值
+ $this->argv = empty($argv) ? ServerStartCommand::exportOptionArray() : $argv;
+
// 初始化 @OnSetup 事件
$this->initSetupAnnotations();
@@ -250,6 +260,73 @@ class Framework
}
}
+ public function bootstrap(): void
+ {
+ foreach ($this->bootstrappers as $bootstrapper) {
+ /* @var Bootstrapper $bootstrapper */
+ (new $bootstrapper())->bootstrap($this);
+ }
+ }
+
+ public function environment(...$environments): string|bool
+ {
+ if (empty($environments)) {
+ return $this->environment;
+ }
+
+ return in_array($this->environment, $environments, true);
+ }
+
+ public function setEnvironment(string $environment): void
+ {
+ $this->environment = $environment;
+ }
+
+ public function isDebugMode(): bool
+ {
+ return $this->debug_mode;
+ }
+
+ public function setDebugMode(bool $debug_mode): void
+ {
+ $this->debug_mode = $debug_mode;
+ }
+
+ public function getLogLevel(): string
+ {
+ return $this->isDebugMode() ? 'debug' : $this->log_level;
+ }
+
+ public function setLogLevel(string $log_level): void
+ {
+ $this->log_level = $log_level;
+ }
+
+ public function getConfigDir(): string
+ {
+ return $this->config_dir;
+ }
+
+ public function setConfigDir(string $config_dir): void
+ {
+ $this->config_dir = $config_dir;
+ }
+
+ public function runningInInteractiveTerminal(): bool
+ {
+ if (function_exists('posix_isatty')) {
+ return posix_isatty(STDIN) && posix_isatty(STDOUT);
+ }
+
+ // fallback to stream_isatty() if posix_isatty() is not available (e.g. on Windows)
+ return function_exists('stream_isatty') && stream_isatty(STDIN) && stream_isatty(STDOUT);
+ }
+
+ public function runningUnitTests(): bool
+ {
+ return defined('PHPUNIT_RUNNING') && constant('PHPUNIT_RUNNING');
+ }
+
/**
* 打印属性表格
*/
@@ -259,7 +336,7 @@ class Framework
// 打印工作目录
$properties['working_dir'] = WORKING_DIR;
// 打印环境信息
- $properties['environment'] = Kernel::getInstance()->environment();
+ $properties['environment'] = $this->environment();
// 打印驱动
$properties['driver'] = config('global.driver');
// 打印logger显示等级
diff --git a/src/ZM/HasRuntimeInfo.php b/src/ZM/HasRuntimeInfo.php
new file mode 100644
index 00000000..9d415ba0
--- /dev/null
+++ b/src/ZM/HasRuntimeInfo.php
@@ -0,0 +1,31 @@
+registerBootstrappers([
- Bootstrap\LoadConfiguration::class, // 加载配置文件
- Bootstrap\LoadGlobalDefines::class, // 加载框架级别的全局常量声明
- Bootstrap\RegisterLogger::class, // 加载 Logger
- Bootstrap\HandleExceptions::class, // 注册异常处理器
- Bootstrap\RegisterEventProvider::class, // 绑定框架的 EventProvider 到 libob 的 Driver 上
- Bootstrap\SetInternalTimezone::class, // 设置时区
- ]);
- }
-
- /**
- * 获取版本号
- */
- public function version(): string
- {
- return ZM_VERSION;
- }
-
- /**
- * 获取配置文件目录
- */
- public function getConfigDir(): string
- {
- return $this->config_dir;
- }
-
- /**
- * 设置配置文件目录
- */
- public function setConfigDir(string $config_dir): void
- {
- $this->config_dir = $config_dir;
- }
-
- /**
- * 获取或检查运行环境
- *
- * @param array|string ...$environments
- */
- public function environment(...$environments): string|bool
- {
- if (empty($environments)) {
- return $this->environment;
- }
-
- return in_array($this->environment, $environments, true);
- }
-
- /**
- * 设置运行环境
- */
- public function setEnvironment(string $environment): void
- {
- $this->environment = $environment;
- }
-
- public function isDebugMode(): bool
- {
- return $this->debug_mode;
- }
-
- public function setDebugMode(bool $debug_mode): void
- {
- $this->debug_mode = $debug_mode;
- }
-
- public function getLogLevel(): string
- {
- return $this->isDebugMode() ? 'debug' : $this->log_level;
- }
-
- public function setLogLevel(string $log_level): void
- {
- $this->log_level = $log_level;
- }
-
- public function runningInConsole(): bool
- {
- return PHP_SAPI === 'cli';
- }
-
- public function runningUnitTests(): bool
- {
- return $this->test_mode;
- }
-
- public function setTestMode(bool $test_mode): void
- {
- $this->test_mode = $test_mode;
- }
-
- public function registerBootstrappers(array $bootstrappers): void
- {
- $this->bootstrappers = array_merge($this->bootstrappers, $bootstrappers);
- }
-
- public function bootstrap(): void
- {
- foreach ($this->bootstrappers as $bootstrapper) {
- /* @var Bootstrapper $bootstrapper */
- (new $bootstrapper())->bootstrap($this);
- }
- }
-}
diff --git a/src/ZM/ZMApplication.php b/src/ZM/ZMApplication.php
index a1ed6bba..42e51f52 100644
--- a/src/ZM/ZMApplication.php
+++ b/src/ZM/ZMApplication.php
@@ -53,6 +53,6 @@ class ZMApplication extends ZMPlugin
$meta = new PluginMeta(name: 'native', plugin_type: ZM_PLUGIN_TYPE_NATIVE);
$meta->bindEntity($this);
PluginManager::addPlugin($meta);
- (new Framework($this->args))->init()->start();
+ Framework::getInstance()->init($this->args)->start();
}
}