hnraytek/flame-module-kernel 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

hnraytek/flame-module-kernel

Composer 安装命令:

composer require hnraytek/flame-module-kernel

包简介

A declarative, auto-discovering, event-driven module kernel for PHP 8+/一款 php 8+ 的声明式、自动发现、事件驱动的模块内核

README 文档

README

一款 PHP 8+ 的声明式、自动发现、事件驱动的模块内核,专为 ThinkPHP 6/8 框架设计。

✨ 特性

  • 声明式编程:使用 PHP 8 属性(Attributes)定义模块元数据,代码即文档
  • 自动发现:自动扫描模块目录和 Composer 包,无需手动注册
  • 事件驱动:内置完善的事件系统,支持前置/后置事件钩子
  • 依赖注入:通过 #[Provides] 自动绑定服务到容器
  • 路由自动注册:基于属性的路由定义,自动注册到 ThinkPHP 路由系统
  • 缓存优化:支持元数据缓存,生产环境高性能运行
  • 模块化架构:轻松构建可插拔的模块化应用

📋 要求

  • PHP >= 8.1
  • ThinkPHP Framework ^6.0 || ^8.0
  • topthink/think-helper ^3.0.3

🚀 快速开始

1. 安装

composer require hnraytek/flame-module-kernel

2. 配置

config/flame.php (可选)自定义模块目录和命名空间

<?php
return [
    'module_path' => root_path('FlameModule'),
    'namespace' => 'FlameModule\\',
];

config/console.php 执行控制台命令

<?php
return [
    'commands' => [
        'flame:discover'  => \Hnraytek\Flame\Module\Command\FlameDiscover::class,
        'flame:install'   => \Hnraytek\Flame\Module\Command\FlameInstall::class,
        'flame:uninstall' => \Hnraytek\Flame\Module\Command\FlameUninstall::class,
        'flame:sync'      => \Hnraytek\Flame\Module\Command\FlameSync::class,
    ],
];

composer.json 用于自动发现和安装模块

{
  "scripts": {
    "pre-package-uninstall": [
      "Hnraytek\\Flame\\Module\\scripts\\ModuleUninstallHandler::preUninstall"
    ],
    "post-autoload-dump": [
      "@php think flame:sync"
    ]
  }
}

3. 创建模块

FlameModule/User/UserModule.php 中:

<?php
namespace FlameModule\User;

use Hnraytek\Flame\Module\Attribute\Module;
use Hnraytek\Flame\Module\Attribute\Provides;
use Hnraytek\Flame\Module\Attribute\Route;
use Hnraytek\Flame\Module\Attribute\Listen;
use Hnraytek\Flame\Module\Attribute\Event;

#[Module(
    name: 'user',
    version: '1.0.0',
    description: '用户管理模块'
)]
#[Provides(UserServiceInterface::class, UserService::class)]
#[Event('user.created', '用户创建事件')]
#[Listen('auth.login', 'UserModule@onLogin', priority: 10)]
class UserModule
{
    #[Route(path: '/users', methods: ['GET'], name: 'users.index')]
    public function index()
    {
        return json(['users' => []]);
    }

    #[Route(path: '/users/:id', methods: ['GET'], name: 'users.show')]
    public function show(int $id)
    {
        return json(['id' => $id]);
    }

    #[Route(path: '/users', methods: ['POST'], name: 'users.store')]
    public function store()
    {
        return json(['message' => 'User created']);
    }

    public function onLogin($event)
    {
        // 处理登录事件
    }
}

4. 初始化

# 首次使用时发现模块
php think flame:discover

# 或者让 Composer 自动处理
composer dump-autoload

完成!模块已自动注册,路由和事件监听器会自动生效。

🎯 核心概念

模块属性 (#[Module])

定义模块的基本信息:

#[Module(
    name: 'module-name',
    version: '1.0.0',
    depends: ['dependency-module'],
    description: '模块描述',
    migration: 'MigrationClass'
)]

参数说明:

  • name: 模块名称
  • version: 版本号
  • depends: 依赖的模块列表
  • description: 模块描述
  • migration: 迁移类(可选)

服务提供 (#[Provides])

将接口绑定到具体实现,自动注册到容器:

#[Provides(UserServiceInterface::class, UserService::class)]
#[Provides(RepositoryInterface::class, UserRepository::class)]
class MyModule
{
    // ...
}

事件声明 (#[Event])

声明模块会触发的事件(用于文档和元数据):

#[Event('user.created', '用户创建后触发')]
#[Event('user.updated', '用户更新后触发')]
class UserModule
{
    // ...
}

事件监听 (#[Listen])

监听其他模块或系统事件:

#[Listen('auth.login', 'MyModule@handleLogin', priority: 10)]
#[Listen('order.created', 'MyModule@onOrderCreated')]
class MyModule
{
    public function handleLogin($event)
    {
        // 处理登录事件
    }

    public function onOrderCreated($event)
    {
        // 处理订单创建事件
    }
}

参数说明:

  • event: 事件名称
  • handler: 处理方法(格式:类名@方法名
  • priority: 优先级(数字越大越先执行,默认 0)

路由定义 (#[Route])

在方法上定义路由,自动注册到 ThinkPHP:

#[Route(path: '/api/users', methods: ['GET'], name: 'api.users.index')]
public function index()
{
    // ...
}

#[Route(
    path: '/api/users/:id',
    methods: ['PUT'],
    name: 'api.users.update',
    middleware: ['auth', 'admin'],
    pattern: ['id' => '\d+'],
    domain: 'api.example.com'
)]
public function update(int $id)
{
    // ...
}

参数说明:

  • path: 路由路径
  • methods: HTTP 方法数组(GET, POST, PUT, DELETE 等)
  • name: 路由名称(可选)
  • middleware: 中间件数组(可选)
  • pattern: 路由参数正则约束(可选)
  • domain: 域名限制(可选)

🔧 高级用法

BaseModuleService - 事务与事件模板

继承 BaseModuleService 获得自动事务管理和事件钩子:

<?php
namespace FlameModule\User\Service;

use Hnraytek\Flame\Module\BaseModuleService;
use Hnraytek\Flame\Module\Event\ModuleEvent;

class UserService extends BaseModuleService
{
    public function createUser(array $data)
    {
        $event = new ModuleEvent($data);

        return $this->execute(
            eventName: 'user.create',
            event: $event,
            business: function (ModuleEvent $event) {
                // 核心业务逻辑(在事务中执行)
                $userData = $event->getData();
                $user = UserModel::create($userData);
                
                return $user;
            },
            afterInTransaction: false // 后置事件在事务外执行
        );
    }
}

执行流程:

  1. 触发 before.user.create 事件(可通过 $event->abort() 中止)
  2. 开启事务,执行业务闭包
  3. 提交事务
  4. 触发 after.user.create 事件(失败不影响主业务)

ModuleEvent - 事件对象

use Hnraytek\Flame\Module\Event\ModuleEvent;

// 创建事件
$event = new ModuleEvent([
    'key1' => 'value1',
    'key2' => 'value2'
]);

// 获取数据
$data = $event->getData();
$value = $event->getData('key1', 'default');

// 设置数据
$event->set('newKey', 'newValue');

// 中止流程(在 before 事件中)
$event->abort('权限不足');

// 检查是否中止
if ($event->isAborted()) {
    echo $event->getAbortReason();
}

自定义路由属性

你可以在路由方法上使用自定义属性,并在中间件中查询:

// 定义自定义属性
#[Attribute(Attribute::TARGET_METHOD)]
class Permission
{
    public function __construct(
        public string $ability
    ) {}
}

// 在模块中使用
class AdminModule
{
    #[Route(path: '/admin/users', methods: ['GET'])]
    #[Permission('user.manage')]
    public function manageUsers()
    {
        // ...
    }
}

// 在中间件中查询
$manager = app(\Hnraytek\Flame\Module\ModuleManager::class);
$attrs = $manager->getRouteAttributes('/admin/users', 'GET');

if (isset($attrs[Permission::class])) {
    $permission = new Permission(...$attrs[Permission::class]);
    // 检查权限...
}

ModuleManager API

use Hnraytek\Flame\Module\ModuleManager;

$manager = app(ModuleManager::class);

// 获取所有模块元数据
$allModules = $manager->getAllModulesMeta();

// 获取指定模块元数据
$moduleMeta = $manager->getModuleMeta(FlameModule\User\UserModule::class);

// 获取路由元数据
$routeMeta = $manager->getRouteMetadata('/users', 'GET');

// 获取路由上的自定义属性
$attributes = $manager->getRouteAttributes('/users', 'GET');

// 检查路由是否有某个属性
$hasAttr = $manager->routeHasAttribute('/users', 'GET', Permission::class);

// 获取所有路由索引
$allRoutes = $manager->getAllRoutes();

// 刷新缓存
$manager->refreshCache();

🛠️ 命令行工具

可用命令

# 发现并缓存所有模块(扫描模块目录和 Composer 包)
php think flame:discover

# 安装指定模块
php think flame:install FlameModule\User\UserModule

# 卸载指定模块
php think flame:uninstall FlameModule\User\UserModule

# 同步所有模块(自动执行安装、升级、卸载)
php think flame:sync

命令说明:

  • flame:discover: 扫描 FlameModule 目录和 Composer 包,发现所有模块并生成缓存
  • flame:install: 手动安装指定模块类(执行迁移、注册服务等)
  • flame:uninstall: 手动卸载指定模块类(执行反向迁移、清理资源等)
  • flame:sync: 智能同步所有模块状态,自动检测需要安装、升级或卸载的模块

Composer Scripts 集成

在项目的 composer.json 中添加以下 scripts,实现自动化管理:

{
  "scripts": {
    "pre-package-uninstall": [
      "Hnraytek\\Flame\\Module\\scripts\\ModuleUninstallHandler::preUninstall"
    ],
    "post-autoload-dump": [
      "@php think flame:sync"
    ]
  }
}

Scripts 说明:

  • pre-package-uninstall: 在 Composer 卸载包之前自动调用模块卸载流程

    • 自动执行 php think flame:uninstall <package-name>
    • 确保模块资源被正确清理
  • post-autoload-dump: 在 Composer 更新 autoload 后自动执行

    • flame:sync: 自动同步所有 Flame 模块状态

使用场景:

# 安装新模块包时,自动同步
composer require vendor/module-package

# 卸载模块包时,自动清理
composer remove vendor/module-package

# 更新依赖后,自动发现和同步模块
composer update

📦 Composer 包集成

第三方包可以通过 composer.json 声明模块:

{
  "name": "vendor/package",
  "extra": {
    "flame": {
      "module": "Vendor\\Package\\PackageModule"
    }
  }
}

模块类会被自动发现和加载。

💡 最佳实践

1. 模块版本管理

#[Module(
    name: 'order',
    version: '2.1.0',  // 遵循语义化版本
    depends: ['user@^1.0', 'payment@>=2.0']  // 依赖版本约束
)]

2. 模块间通信

// 方式 1: 通过事件
$this->emit('order.created', new ModuleEvent(['order_id' => $id]));

// 方式 2: 通过服务容器
$orderService = app(OrderServiceInterface::class);

// 方式 3: 直接调用(不推荐,耦合度高)

3. 错误处理

public function createUser(array $data)
{
    try {
        return $this->execute(
            eventName: 'user.create',
            event: new ModuleEvent($data),
            business: function (ModuleEvent $event) {
                // 业务逻辑
            }
        );
    } catch (\Exception $e) {
        // 记录日志、返回错误等
        Log::error('User creation failed: ' . $e->getMessage());
        throw $e;
    }
}

5. 测试模块

// tests/ModuleTest.php
use Hnraytek\Flame\Module\ModuleManager;

class ModuleTest extends TestCase
{
    public function testModuleDiscovery()
    {
        $manager = app(ModuleManager::class);
        $modules = $manager->getAllModulesMeta();
        
        $this->assertArrayHasKey('user', $modules);
        $this->assertEquals('1.0.0', $modules['user']['version']);
    }
    
    public function testRouteRegistration()
    {
        $manager = app(ModuleManager::class);
        $route = $manager->getRouteMetadata('/users', 'GET');
        
        $this->assertNotNull($route);
        $this->assertEquals('users.index', $route['name']);
    }
}

🎨 完整示例

<?php
namespace FlameModule\Order;

use Hnraytek\Flame\Module\Attribute\Module;
use Hnraytek\Flame\Module\Attribute\Provides;
use Hnraytek\Flame\Module\Attribute\Route;
use Hnraytek\Flame\Module\Attribute\Listen;
use Hnraytek\Flame\Module\BaseModuleService;
use Hnraytek\Flame\Module\Event\ModuleEvent;

#[Module(
    name: 'order',
    version: '2.0.0',
    depends: ['user'],
    description: '订单管理模块'
)]
#[Provides(OrderServiceInterface::class, OrderService::class)]
#[Listen('payment.completed', 'OrderModule@onPaymentCompleted')]
class OrderModule
{
    #[Route(path: '/orders', methods: ['GET'], name: 'orders.index')]
    public function index()
    {
        return json(['orders' => []]);
    }

    #[Route(path: '/orders', methods: ['POST'], name: 'orders.create')]
    public function create()
    {
        $service = app(OrderService::class);
        return json($service->createOrder(request()->post()));
    }

    public function onPaymentCompleted(ModuleEvent $event)
    {
        // 处理支付完成事件
        $orderId = $event->getData('order_id');
        // 更新订单状态...
    }
}

class OrderService extends BaseModuleService
{
    public function createOrder(array $data)
    {
        $event = new ModuleEvent($data);

        return $this->execute(
            eventName: 'order.create',
            event: $event,
            business: function (ModuleEvent $event) {
                $orderData = $event->getData();
                $order = OrderModel::create($orderData);
                
                // 触发订单创建事件
                $this->emit('order.created', new ModuleEvent([
                    'order_id' => $order->id
                ]));
                
                return $order;
            }
        );
    }
}

运行此示例:

# 1. 创建模块文件后
# 2. 刷新缓存
php think flame:discover

# 3. 或使用自动同步
composer dump-autoload

# 4. 访问路由
curl http://your-domain/orders

❓ 常见问题

Q: 模块没有被发现?

A: 检查以下几点:

  1. 模块类是否在配置的 module_path 目录下
  2. 模块类是否有 #[Module] 属性
  3. 命名空间是否正确(应与 FlameModule\ 前缀匹配)
  4. 执行 php think flame:discover 刷新缓存
  5. 检查 runtime/flame_modules_cache.php 是否生成

Q: 路由无法访问?

A: 确认:

  1. 模块已被成功发现(查看缓存文件)
  2. 路由方法是否为 public
  3. HTTP 方法是否匹配
  4. 中间件配置是否正确

Q: 如何调试模块加载问题?

A:

# 查看详细日志
php think flame:discover -v

# 检查缓存内容
cat runtime/flame_modules_cache.php

# 查看已注册的模块
php think eval "\print_r(app(\Hnraytek\Flame\Module\ModuleManager::class)->getAllModulesMeta(), true);"

Q: Composer 包模块不工作?

A: 确保包的 composer.json 包含:

{
  "extra": {
    "flame": {
      "module": "Vendor\\Package\\PackageModule"
    }
  }
}

然后执行 composer dump-autoload

Q: 如何禁用某个模块?

A: 有三种方式:

  1. FlameModule 目录移除模块文件
  2. 卸载 Composer 包
  3. 在模块中添加条件判断(不推荐)

📁 项目结构


your-project/
├── FlameModule/              # 模块目录
│   ├── User/
│   │   └── UserModule.php
│   ├── Order/
│   │   └── OrderModule.php
│   └── Auth/
│       └── AuthModule.php
├── config/
│   ├── flame.php            # Flame 模块配置
│   └── console.php          # 控制台命令配置
├── composer.json            # 包含 scripts 配置
└── vendor/
    ├── flame_modules_cache.php  # 缓存文件(自动生成)
    ├── installed-modules.php    # 已安装模块缓存(自动生成)
    └── hnraytek/
        └── flame-module-kernel/ # FlameModuleKernel 核心

🧪 测试

composer install --dev
./vendor/bin/phpunit test/

📝 许可证

Apache-2.0 License

👤 作者

🤝 贡献

欢迎提交 Issue 和 Pull Request!

☕️ 支持项目

如果这个项目对你有帮助,请给个 Star ⭐

作为一个个人开发者,维护这个项目投入了大量的深夜时光和咖啡。如果这个项目帮到了您,希望您能请我喝一杯咖啡。

您的赞助不仅能让我多活几天(字面意思),也能让项目持续迭代,修复更多Bug。 img.png

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: Apache-2.0
  • 更新时间: 2026-06-15

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固