基于workerman 开发了一个web框架,要忙别的去了。有没有人接着干的

wasoncheung

问题描述

这里写问题描述

框架,结合了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);
    }
}
407 3 0
3个回答

xiaobai

可以啊。大佬。

  • 暂无评论
luohonen

webman已经够可以了,没必要新的框架

  • wasoncheung 2023-02-25

    webman历史包袱太重了。很多都写死了。很多组件要适用业务就得改,但是改的多了就很混乱了

PHP甩JAVA一条街

我是5年老php人员, 为啥你的代码很6, 你多少年经验?

  • wasoncheung 2023-02-25

    取笑了,毫无经验。就是折腾的多。之前都是用java

年代过于久远,无法发表回答
🔝