这里写问题描述
框架,结合了thinkphp和workerman的优点,采用容器作为管理,将流程 分为 初始化,启动,运行。三个阶段。
每个阶段均用接口进行了抽象,可以无缝追加业务和切换运行模式。阶段内部均有事件支持,比如多语言加载事件,内容发送前,发送后事件。
目前 还是控制器解析部分没有完成了。本人开发了大半了,
真的累,很多包说是可以无缝使用,其实有很多隐藏的bug并不适合worker的运行方式。
此前一直用springboot开发,就想着把约定大于配置这一套带到php去,而且现在的php也支持Attribute了,也希望这个特性能充分利用起来
比如我自己实现的容器管理,已经实现了自动注入#[Autowried] 和#[GetConfig]两个了
有闲心的大佬可以评论区留言,拿去接着开发~
这是启动类,也是一切的入口。
<?php
declare(strict_types=1);
namespace panda;
use panda\Bootstraps\LoadEvents;
use panda\Bootstraps\LoadLang;
use panda\Bootstraps\LoadProviders;
use panda\Bootstraps\LoadSystemLang;
use panda\container\Container;
use panda\Contract\AppInterface;
use panda\Events\AfterAppRun;
use panda\Events\AfterBoostrap;
use panda\Events\AfterInitialize;
use panda\Events\BeforeAppRun;
use panda\Events\BeforeBootstrap;
use panda\Events\BeforeInitialize;
use panda\Exception\AppRunException;
use panda\Exception\BootstrapException;
use panda\Exception\InitializerException;
use panda\Initializers\AppStatusInit;
use panda\Initializers\LoadBuiltinFunctions;
use panda\Initializers\LoadConfigFiles;
use panda\Initializers\LoadEnvFiles;
use panda\Initializers\LoadFunctions;
use panda\Initializers\MergeEnvConfigs;
/**
* @Data: 2023/2/7
* @Author: WasonCheung
* @Description: 应用类
*
* @property Config $config 配置 down
* @property Env $env 配置环境 down
* @property Event $event 事件管理 down
* @property Path $path 路径信息 down
* @property Classes $classes 系统信息 down
* @property Lang $lang 多语言 down
* @property Log $log 日志 down
* @property Cache $cache 缓存 down
* @property ErrorHandler $errorHandler 异常处理
* @property Initializer $initializer 初始化器
* @property Boostrap $boostrap 启动器
* @property Runner $runner 运行器
*/
class Panda extends Container implements AppInterface
{
// debug
protected static bool $debug = false;
// 容器别名
protected array $providers = [
'config' => Config::class,
'env' => Env::class,
'event' => Event::class,
'path' => Path::class,
'classes' => Classes::class,
'panda' => Panda::class,
'lang' => Lang::class,
'log' => Log::class,
'cache' => Cache::class,
'errorHandler' => ErrorHandler::class,
'initializer' => Initializer::class,
'boostrap' => Boostrap::class,
'runner' => Runner::class,
];
// 初始化器
protected array $initializers = [
// 环境配置加载
LoadEnvFiles::class,
// 加载公共函数
LoadFunctions::class,
// 加载内置函数
LoadBuiltinFunctions::class,
// 加载配置文件
LoadConfigFiles::class,
// 合并环境配置到全局配置
MergeEnvConfigs::class,
// 初始化应用状态
AppStatusInit::class,
];
// 启动
protected array $bootstraps = [
// 加载容器配置
LoadProviders::class,
// 加载事件配置
LoadEvents::class,
// 加载系统多语言
LoadSystemLang::class,
// 加载多语言
LoadLang::class,
];
// 运行
protected array $runners = [];
// 事件
protected array $listeners = [];
/**
* @return bool
* @Data: 2023/2/11
* @Author: WasonCheung
* @Description: 是否是debug
*/
public static function isDebug(): bool
{
return self::$debug;
}
/**
* @param bool $debug
* @return $this
* @Data: 2023/2/13
* @Author: WasonCheung
* @Description: 设置debug状态
*/
public function setDebug(bool $debug): self
{
self::$debug = $debug;
return $this;
}
/**
* @param string $timezone
* @return $this
* @Data: 2023/2/13
* @Author: WasonCheung
* @Description: 设置时区
*/
public function setTimezone(string $timezone): self
{
date_default_timezone_set($timezone);
return $this;
}
/**
* @return $this
* @throws AppRunException
* @throws \Throwable
* @Data: 2023/2/12
* @Author: WasonCheung
* @Description: 启动
*/
public function appBoot(): self
{
try {
// 启动器开始事件
$this->event->trigger(BeforeBootstrap::class);
// 启动
$this->boostrap->dispatcher();
// 应用启动
$this->getRunClass()->appBoot();
// 启动器结束
$this->event->trigger(AfterBoostrap::class);
} catch (\Throwable $e) {
$this->errorHandler->resolve(new BootstrapException($e));
}
return $this;
}
/**
* @return AppInterface
*/
public function getRunClass(): AppInterface
{
if (!$this->has(AppInterface::class)) {
$this->setRunClass(Command::class);
}
return $this->get(AppInterface::class);
}
/**
* @param string $runClass
* @return $this
* @Data: 2023/2/13
* @Author: WasonCheung
* @Description: 设置运行类
*/
public function setRunClass(string|AppInterface $runClass): self
{
$this->set(AppInterface::class, $runClass);
return $this;
}
/**
* @Data: 2023/2/7
* @Author: WasonCheung
* @Description: 运行
*/
public function appRun(): void
{
try {
// 应用开始
$this->event->trigger(BeforeAppRun::class);
// 启动链
$this->runner->dispatcher();
// 应用运行
$this->getRunClass()->appRun();
// 应用结束
$this->event->trigger(AfterAppRun::class);
} catch (\Throwable $e) {
$this->errorHandler->resolve(new AppRunException($e));
}
}
/**
* @return array
* @Data: 2023/2/17
* @Author: WasonCheung
* @Description: 获取
*/
public function getRunners(): array
{
return $this->runners;
}
/**
* @param array $runners
* @return $this
* @Data: 2023/2/17
* @Author: WasonCheung
* @Description: 设置运行器
*/
public function setRunners(array $runners): self
{
$this->runners = $runners;
return $this;
}
/**
* @return array|string[]
* @Data: 2023/2/17
* @Author: WasonCheung
* @Description: 获取
*/
public function getBootstraps(): array
{
return $this->bootstraps;
}
/**
* @param array $bootstraps
* @Data: 2023/2/17
* @Author: WasonCheung
* @Description: 设置启动器
*/
public function setBootstraps(array $bootstraps): void
{
$this->bootstraps = $bootstraps;
}
/**
* @return $this
* @throws AppRunException
* @throws \Throwable
* @Data: 2023/2/12
* @Author: WasonCheung
* @Description: 初始化
*/
public function appInit(): self
{
try {
ini_set('display_errors', 'on');
error_reporting(E_ALL);
// 环境配置初始化
if (!$this->has(Env::class)) {
$this->setEnv('dev');
}
// 路径初始化
if (!$this->has(Path::class)) {
$this->setPath(\dirname(__DIR__, 3) . DIRECTORY_SEPARATOR);
}
// 注册应用容器
$this
->set($this->getProviders())
->set($this->getRunClass()->getProviders());
// 注册全局事件
$this->event
->pushListeners($this->getListeners())
->pushListeners($this->getRunClass()->getListeners())
->trigger(BeforeInitialize::class);
// 调用初始化器
$this->initializer->dispatcher();
// 应用初始化
$this->getRunClass()->appInit();
$this->event->trigger(AfterInitialize::class);
} catch (\Throwable $e) {
$this->errorHandler->resolve(new InitializerException($e));
}
return $this;
}
/**
* @param string|Env $env
* @return $this
* @Data: 2023/2/13
* @Author: WasonCheung
* @Description: 设置环境变量
*/
public function setEnv(string|Env $env): self
{
$this->set(Env::class, $env instanceof Env ? $env : [$env]);
return $this;
}
/**
* @param string|Path $path
* @return $this
* @Data: 2023/2/13
* @Author: WasonCheung
* @Description: 设置路径
*/
public function setPath(string|Path $path): self
{
$this->set(Path::class, $path instanceof Path ? $path : [$path]);
return $this;
}
/**
* @return array|string[]
* @Data: 2023/2/17
* @Author: WasonCheung
* @Description: 获取容器定义
*/
public function getProviders(): array
{
return $this->providers;
}
/**
* @param array $providers
* @Data: 2023/2/17
* @Author: WasonCheung
* @Description: 设置容器
*/
public function setProviders(array $providers): void
{
$this->providers = array_merge($this->providers, $providers);
}
/**
* @return array
* @Data: 2023/2/17
* @Author: WasonCheung
* @Description: 获取监听器
*/
public function getListeners(): array
{
return $this->listeners;
}
/**
* @param array $listeners
* @return $this
* @Data: 2023/2/17
* @Author: WasonCheung
* @Description: 设置事件
*/
public function setListeners(array $listeners): self
{
$this->listeners = $listeners;
return $this;
}
/**
* @return array|string[]
* @Data: 2023/2/17
* @Author: WasonCheung
* @Description: 初始化器
*/
public function getInitializers(): array
{
return $this->initializers;
}
/**
* @param array $initializers
* @return $this
* @Data: 2023/2/17
* @Author: WasonCheung
* @Description: 设置
*/
public function setInitializers(array $initializers): self
{
$this->initializers = $initializers;
return $this;
}
public function __get(string $name)
{
return $this->get($name);
}
public function __set(string $name, $value): void
{
$this->set($name, $value);
}
}
可以啊。大佬。
webman已经够可以了,没必要新的框架
webman历史包袱太重了。很多都写死了。很多组件要适用业务就得改,但是改的多了就很混乱了
我是5年老php人员, 为啥你的代码很6, 你多少年经验?
取笑了,毫无经验。就是折腾的多。之前都是用java