dleno / common-core
common core
Requires
- php: >=8.1
- ext-curl: *
- ext-swoole: >=5.0
- dleno/dingtalk: ~3.1.0
- dleno/hyperf-env-multi: ~3.1.0
- hashids/hashids: ^4.1
- hyperf/amqp: ~3.1.0
- hyperf/async-queue: ^3.1
- hyperf/cache: ~3.1.0
- hyperf/command: ~3.1.0
- hyperf/config: ~3.1.0
- hyperf/crontab: ~3.1.0
- hyperf/database: ~3.1.0
- hyperf/db-connection: ~3.1.0
- hyperf/engine: ^2.10
- hyperf/framework: ~3.1.0
- hyperf/guzzle: ~3.1.0
- hyperf/http-server: ~3.1.0
- hyperf/json-rpc: ~3.1.0
- hyperf/laminas-mime: ^3.0
- hyperf/logger: ~3.1.0
- hyperf/memory: ~3.1.0
- hyperf/paginator: ~3.1.0
- hyperf/process: ~3.1.0
- hyperf/redis: ~3.1.0
- hyperf/rpc-client: ~3.1.0
- hyperf/signal: ~3.1.0
- hyperf/snowflake: ~3.1.0
- hyperf/utils: ~3.1.0
- hyperf/validation: ~3.1.0
- jenssegers/optimus: ^1.1
- symfony/property-access: ^5.4
- symfony/serializer: ^5.4
Requires (Dev)
- swoole/ide-helper: ^5.0
README
dleno/common-core 是 Dleno Hyperf 3.1 项目的公共核心包,负责沉淀 HTTP/RPC/Model/AMQP/AsyncQueue/WebSocket 等基础能力,以及项目通用工具、全局函数、异常输出、日志输出、分布式锁和示例模板。
它的定位是“框架基座 + 业务可接入的公共组件”,不是一个完整业务应用。业务项目只需要安装包、补齐少量 DI 绑定和业务策略,就可以复用统一的请求解析、输出格式、模型能力、队列封装、WebSocket 连接管理和在线检查能力。
环境要求
- PHP
>= 8.1 - Swoole
>= 5.0 - Hyperf
~3.1 - ext-curl
- WebSocket 功能依赖 Redis
7.4+的HEXPIRE能力
启用 WebSocket 服务时,启动前会校验:
server.mode必须是SWOOLE_BASE,否则直接终止启动。- Redis 可达但不支持
HEXPIRE时直接终止启动。 - Redis 暂时不可达时只输出 WARN 放行,避免启动编排中的短暂网络抖动误杀服务;运行时仍要求 Redis 7.4+ 可用。
安装
composer require dleno/common-core:^3.1
安装后包内 ConfigProvider 会自动生效:
- 扫描
src/下的注解。 - 自动加载
src/common/Functions.php全局函数。 - 通过
dleno/hyperf-env-multi显式加载环境文件:先加载.env,再按APP_ENV加载.env.<APP_ENV>,环境文件中的同名变量以后者为准。 - 注入部分基础 dependencies。
- 按
ENABLE_HTTP/ENABLE_WS自动注入 HTTP / WS 基础中间件。 - 提供 WebSocket 配置发布模板,可通过
vendor:publish写入config/autoload/websocket.php。
发布配置:
php bin/hyperf.php vendor:publish dleno/common-core
接入清单
HTTP 请求对象绑定
Hyperf 自身也会绑定 RequestParserInterface 和 RequestInterface,因此这两个绑定需要放在业务项目 config/autoload/dependencies.php,确保优先级稳定:
return [ Hyperf\HttpMessage\Server\RequestParserInterface::class => Dleno\CommonCore\Core\Request\RequestParser::class, Hyperf\HttpServer\Contract\RequestInterface::class => Dleno\CommonCore\Core\Request\Request::class, ];
CoreMiddleware 和 DispatcherFactory 已由 common-core 的 ConfigProvider 注入,通常不需要业务项目重复绑定。
HTTP 模块前置中间件绑定
common-core 会在 HTTP InitMiddleware 之后自动注册 AbstractModuleBeforeMiddleware,并默认绑定到包内 DefaultModuleBeforeMiddleware。默认实现会按 config('app.api_check_sign') / config('app.api_data_crypt') 执行签名校验和请求解密,checkAuth() 为 no-op,checkReplay() 返回 true 放行。
业务需要登录校验、防重放或自定义签名参数时,推荐继承 DefaultModuleBeforeMiddleware,只覆写需要的钩子,并在业务项目 config/autoload/dependencies.php 中覆盖抽象基类绑定:
return [ Dleno\CommonCore\Middleware\Http\AbstractModuleBeforeMiddleware::class => App\Middleware\AppModuleBeforeMiddleware::class, ];
如未覆盖该绑定,会使用包内默认实现:签名/解密仍按配置开关执行,但不会做业务登录校验或防重放拦截。
参考实现见:
examples/Middleware/AppModuleBeforeMiddleware.php
异常处理器配置
异常处理链顺序敏感,DefaultExceptionHandler 会兜底并终止后续传播。因此 common-core 不通过 ConfigProvider 自动注入 exceptions.handler,而是提供 ExceptionHandlerConfig 让业务项目在 config/autoload/exceptions.php 中显式生成默认链,并保留业务 handler 的插入位置:
use Dleno\CommonCore\Exception\ExceptionHandlerConfig; return [ 'handler' => ExceptionHandlerConfig::defaultHandlers( httpCommonHandlers: [ App\Exception\Handler\BusinessCommonExceptionHandler::class, ], wsCommonHandlers: [ App\WebSocket\Exception\Handler\BusinessCommonWsExceptionHandler::class, ], httpBeforeDefault: [ App\Exception\Handler\BusinessOutputExceptionHandler::class, ], wsBeforeDefault: [ App\WebSocket\Exception\Handler\BusinessWsOutputExceptionHandler::class, ], ), ];
httpCommonHandlers / wsCommonHandlers 会插入到 common-core 的 CommonExceptionHandler 之后,用于回滚、审计、上下文清理等公共前置处理,不应调用 stopPropagation();httpBeforeDefault / wsBeforeDefault 会插入到对应协议的 DefaultExceptionHandler 之前,用于业务输出类 handler。未启用 ENABLE_HTTP / ENABLE_WS 时不会生成对应 server 的异常链。
WebSocket 业务策略绑定
WebSocket 的连接维度属于业务决策,common-core 不提供默认绑定策略。业务项目必须在 dependencies.php 中绑定 WsBindStrategyInterface:
return [ Dleno\CommonCore\Websocket\Contract\WsBindStrategyInterface::class => App\WebSocket\Bind\DefaultWsBindStrategy::class, ];
WsHookInterface 已有 no-op 默认实现,业务不需要身份解析、握手校验或生命周期钩子时可以不覆盖;需要接入登录态、握手鉴权、open/close/heartbeat/message/send 等业务逻辑时再绑定:
return [ Dleno\CommonCore\Websocket\Contract\WsHookInterface::class => App\WebSocket\Hook\AppWsHook::class, ];
参考实现见:
examples/WebSocket/Bind/DefaultWsBindStrategy.phpexamples/WebSocket/Bind/MultiDimWsBindStrategy.phpexamples/WebSocket/Hook/AppWsHook.php
核心能力
HTTP 基座
相关目录:
src/Base/BaseCoreController.phpsrc/Middleware/Httpsrc/Core/Requestsrc/Core/Routesrc/Annotationsrc/Aspect
主要能力:
- Controller 自动注入对应 Service。
successData()统一返回结构。checkParams()参数校验。LockCheckTrait提供分布式锁辅助。OutputHtml、OutputNoLog、OutputNotFormat等注解控制输出格式、日志和字段格式化。- HTTP 输出切面自动记录响应日志,并在
API_DATA_CRYPT开启时加密响应体。 - HTTP 请求初始化、语言/时区/traceId 等上下文处理。
- 路由分发增强和请求对象替换。
- AutoController 请求方式控制:方法级
#[AllowMethods]优先,其次类级AutoController(defaultMethods)、config('app.default_allow_methods')、默认['POST', 'GET'];包含GET时自动补HEAD,OPTIONS预检由InitMiddleware统一处理。 - 模块前置中间件提供签名校验、请求解密、登录校验和防重放钩子。
AbstractModuleBeforeMiddleware封装流程,DefaultModuleBeforeMiddleware提供默认钩子实现,业务通常继承默认实现后在dependencies.php绑定抽象基类来接管。该中间件只处理已命中路由(FOUND);NOT_FOUND/METHOD_NOT_ALLOWED会放行给管线末端CoreMiddleware返回 404 / 405,避免未知路由被误判为签名错误。
示例:
examples/Httpexamples/Middlewareexamples/Config
异常与输出
相关目录:
src/Exceptionsrc/Tools/OutPut.phpsrc/Tools/Outputsrc/Tools/Logger.php
主要能力:
- HTTP/RPC 常用异常处理器。
ExceptionHandlerConfig生成 HTTP / WS 默认异常链,并支持业务公共前置 handler、兜底前输出 handler 插入到固定位置。- 统一 JSON 输出。
- API/RPC/Error 输出日志封装。
- HTTP/WS Controller 响应日志切面。
- 按渠道输出 stdout、system、api、sql、business 日志。
- 错误输出可读取业务
config/autoload/dingtalk.php的dingtalk.trace配置发送异常追踪通知。
Model 与数据库
相关目录:
src/Modelsrc/Db
主要能力:
BaseModel统一模型基类。- 自定义
EloquentBuilder,支持分页、分组统计、批量插入更新、全文检索等项目增强方法。 - 支持按年/月/日/周/固定数量分表。
findById()、updateById()、deleteById()按主键路由到对应分表。withTable()支持指定分表后缀查询。- 模型生成时保持 decimal 精度处理。
示例:
examples/Model/BaseModel.phpexamples/Model/Test.phpexamples/Model/TestSplit.php
AMQP
相关目录:
src/Base/Amqpsrc/Tools/Amqp
主要能力:
BaseProducer、BaseConsumer封装 Hyperf AMQP。- 支持延迟交换机。
- 支持死信交换机、死信路由、消息 TTL、队列 TTL。
- 支持生产者确认。
- 支持静态队列和按服务器动态 routingKey / queue。
示例:
examples/Amqpexamples/Amqp/Dynamic
AsyncQueue
相关目录:
src/Base/AsyncQueuesrc/Tools/AsyncQueue
主要能力:
BaseJob统一队列 Job 基类。BaseQueueConsumer统一消费进程基类。BaseDriverFactory支持动态队列驱动配置。AsyncQueue::push()会按 Job 的 queue 自动选择对应 driver。- 支持静态队列和按服务器动态队列。
示例:
examples/AsyncQueueexamples/AsyncQueue/Dynamic
WebSocket
相关目录:
src/Websocketpublish/websocket.php
主要能力:
- WebSocket 握手鉴权中间件。
- WS Controller 注解和消息路由。
- 生命周期 Hook:握手前/中/后、open、close、heartbeat、message、send 等。
- 连接绑定策略:
bindDimensions()、addressableDimensions()、onlineCheckDimensions()、uniqueDimensions()。 - 按维度推送:单 fd、批量 fd、广播、按业务维度推送。
- 连接唯一性:支持同账号单连接、同账号同设备单连接等踢旧策略。
- 实时在线检查:
checkRealtimeOnlineByDim(),适合小批量、强实时、unique 维度。 - 心跳在线检查:
checkHeartbeatOnlineByDim(),基于 Redis 7.4+HEXPIRE和 presence bucket 索引,适合大批量心跳级判断。 - 全量心跳在线快照:
checkHeartbeatOnlineAllByDim(),适合后台/统计类低频场景。 - per-server 实时消息队列和可选独立控制队列,避免在线核验/断连阻塞真实消息下发。
维度配置建议:
addressableDimensions()用于“能不能按这个维度推送/寻址”。onlineCheckDimensions()用于“能不能按这个维度做心跳在线检查”。uniqueDimensions()用于“这个维度是否单连接/踢旧”。- 低基数维度如
device_type=ios/android/h5可以用于推送寻址,但不应放入onlineCheckDimensions(),否则单个 value 可能挂大量连接,在线检查会变重。 - 高基数且单 value 连接数可控的维度,如
account_id,更适合做在线检查。
WebSocket 配置见 config/autoload/websocket.php,模板来源为 publish/websocket.php。重点配置:
key_prefix: WS Redis key 前缀。local_enable: local 环境是否启用 WS 常驻进程。server_set_cache_ms: 在线服务器集合短缓存。presence_bucket_num: 心跳 presence 索引 bucket 数。realtime_online.max/realtime_online.timeout: 实时在线核验批量上限与等待超时。queue: 实时消息队列消费进程与并发配置。dedicated_queue: 独立控制队列配置。
示例:
examples/WebSocket
JsonRpc / MQ RPC
相关目录:
src/JsonRpc
主要能力:
- JSON-RPC 客户端代理。
- MQ 异步 RPC 封装。
- MQ RPC 失败重试和异常链保留。
示例:
examples/Tools/UsageExamples.php
工具类
相关目录:
src/Toolssrc/Traitssrc/common/Functions.php
常用能力:
DcsLock: Redis 分布式锁,支持等待、自动续期、Lua 解锁。HttpClient: 协程内走 Swoole Coroutine Client,非协程内走 curl。OpenSslCrypt: AES/DES 对称加解密。OpenSslRsa/OpenSslRsa2: RSA 分块加解密。两者协议不同——OpenSslRsa密文为 hex(偏长),OpenSslRsa2密文为 base64(约短一半)。接口加密的Client-Key(AES 密钥)解密走OpenSslRsa2,客户端须使用同款算法加密。CheckVal/CheckParams: 常用格式校验和参数校验。Client/Server: 客户端信息、IP、设备、语言、路由、traceId 等辅助。ArrayTool、Strings、TimeTool、Distribution等工具。ObjectAttribute: 对象属性填充/导出辅助。
示例:
examples/Tools/UsageExamples.php
examples 目录
examples/ 是使用示例集合,不会随包安装自动执行。
安全边界:
composer.json只 autoloadsrc/,不加载examples/。ConfigProvider只扫描src/,不扫描examples/。- 示例命名空间为
Dleno\CommonCore\Examples\...,不会占用业务App\...。 - AMQP Consumer 示例的
isEnable()保留AMQP_ENABLE前置门禁;Crontab 示例保留ENABLE_CRONTAB前置门禁;随后都会拦截local环境并默认return false,避免误扫后真实执行。 - HTTP Controller、WS Controller 示例刻意不直接声明
#[AutoController]、#[WsController],复制到业务项目后再按注释启用。
使用方式:
- 复制需要的示例到业务项目
app/下对应目录。 - 修改 namespace,例如改成
App\WebSocket\Bind。 - 根据业务把
isEnable()改成自己的启用条件;复制后建议保留AMQP_ENABLE/ENABLE_CRONTAB等功能开关和local环境强制关闭判断。 - 不要直接把
vendor/dleno/common-core/examples加入业务注解扫描路径。
常用环境变量
基础开关:
APP_NAME: 应用名,Redis key 前缀等通用配置会使用。APP_ENV: 当前运行环境;存在.env.<APP_ENV>时会覆盖.env中的同名变量。IS_PROD: 强制判定为正式环境;未设置时config('app_env') === 'prod'也会视为正式环境。ENABLE_HTTP: 是否启用 HTTP server 相关基础中间件。ENABLE_WS: 是否启用 WebSocket 相关进程和中间件。HTTP_INIT_MIDDLEWARE_ENABLE: 是否自动注入 HTTP 初始化中间件和模块前置中间件,默认开启。WS_AUTH_MIDDLEWARE_ENABLE: 是否自动注入 WS 鉴权中间件,默认开启。LOG_MAX_FILES: 默认日志文件保留数量。
WebSocket:
WS_KEY_PREFIXWS_LOCAL_ENABLEWEBSOCKET_COMPRESSIONWS_SERVER_SET_CACHE_MSWS_PRESENCE_BUCKET_NUMWS_REALTIME_ONLINE_MAXWS_REALTIME_ONLINE_TIMEOUTWS_CONSUMER_PROCESSESWS_CONSUMER_LIMITWS_CONSUMER_MAX_MESSAGESWS_DEDICATED_QUEUE_ENABLEWS_DEDICATED_PROCESSESWS_DEDICATED_LIMITWS_DEDICATED_MAX_MESSAGES
连接池与外部服务:
DB_HOSTDB_MIN_CONNECTION/DB_MAX_CONNECTIONDB_CONNECT_TIMEOUT/DB_WAIT_TIMEOUTDB_HEARTBEAT/DB_MAX_IDLE_TIMEDB_READ_HOST/DB_WRITE_HOSTDB_READ_MIN_CONNECTION/DB_READ_MAX_CONNECTIONDB_READ_CONNECT_TIMEOUT/DB_READ_WAIT_TIMEOUTDB_READ_HEARTBEAT/DB_READ_MAX_IDLE_TIMEDB_WRITE_MIN_CONNECTION/DB_WRITE_MAX_CONNECTIONDB_WRITE_CONNECT_TIMEOUT/DB_WRITE_WAIT_TIMEOUTDB_WRITE_HEARTBEAT/DB_WRITE_MAX_IDLE_TIMEREDIS_MIN_CONNECTION/REDIS_MAX_CONNECTIONREDIS_CONNECT_TIMEOUT/REDIS_WAIT_TIMEOUTREDIS_HEARTBEAT/REDIS_MAX_IDLE_TIMEAMQP_CONNECTION/AMQP_MIN_CONNECTION/AMQP_MAX_CONNECTIONAMQP_CONNECT_TIMEOUT/AMQP_WAIT_TIMEOUTAMQP_READ_WRITE_TIMEOUT/AMQP_HEARTBEATAMQP_MAX_IDLE_CHANNELSCONSUL_SERVER_URIRPC_CONNECT_TIMEOUT/RPC_RECV_TIMEOUTRPC_MIN_CONNECTION/RPC_MAX_CONNECTIONRPC_WAIT_TIMEOUT/RPC_HEARTBEAT/RPC_MAX_IDLE_TIME
测试与校验
本包当前 composer test 执行 PHP 语法检查,覆盖 src、publish、examples:
composer test
Composer 文件校验:
composer validate --strict
目录结构
src/ 核心源码
publish/ 可发布配置模板
examples/ 使用示例,不会自动加载或执行
.github/workflows/ Release 等自动化工作流
设计原则
- 核心协议和运行时约束放在 common-core 内统一维护。
- 业务差异通过策略、Hook、配置和示例复制接入。
- WebSocket 低层队列、注册、presence、在线检查逻辑不建议业务继承改写。
- 启动期能确定的错误尽量 fail-fast,但 Redis 暂时不可达只告警,避免误杀编排过程中的短暂抖动。
- 示例代码只作为模板,不作为运行时功能的一部分。