Download the PHP package kode/runtime without Composer
On this page you can find all versions of the php package kode/runtime. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package runtime
kode/runtime —— 跨平台运行时抽象层
一个为现代 PHP 常驻内存应用设计的统一运行时抽象包 支持 Swoole、Swow、PHP Fiber(协程)、多进程、多线程、Console 及传统 CLI 模式 面向 PHP 8.4+,基于 enum、#[\Override]、typed class constants、Fiber 协作式调度器等 PHP 8.3 新特性构建
📦 包信息
| 项目 | 内容 |
|---|---|
| 包名 | kode/runtime |
| PHP 版本 | ^8.4 |
| 许可证 | Apache-2.0 |
| 维护状态 | Active |
| GitHub | https://github.com/kodephp/runtime |
| Packagist | kode/runtime |
依赖包
| 包名 | 版本 | 说明 |
|---|---|---|
php |
^8.4 |
运行环境(必需) |
kode/context |
^3.0 |
协程/纤程上下文管理(必需) |
kode/console |
^4.0 |
控制台输入输出(必需,用于 ConsoleRuntime 装饰器与 RuntimeCommand 命令基类) |
可选并发能力通过 PHP 扩展提供:
ext-swoole、ext-swow、ext-pcntl、ext-parallel。
🎯 设计目标
为构建 常驻内存型 PHP 框架 提供底层运行时抽象能力:
- 🔌 统一不同协程引擎(Swoole / Swow / Fiber)的 API 差异
- 🔄 提供一致的异步编程模型(
async/run/parallel/channel/defer) - 🏗️ 支持多进程(
pcntl_fork)、多线程(ext-parallel)环境 - 🎨 Console 作为输出增强层(装饰器模式),不再抢占自动探测导致降级
- 🔒 协程安全的上下文管理
- ⚡ 内置协作式
FiberScheduler,使 Fiber 模式下的sleep/Channel阻塞真正让出执行权而非忙等
✅ 核心功能
| 功能 | 说明 |
|---|---|
| 🔍 运行环境枚举 | RuntimeEnvironment 类型安全枚举,自动检测 Swoole → Swow → Fiber → CLI |
| 🔄 统一协程启动 | Runtime::async() / 全局函数 go() |
| 🏁 run / parallel | run(callable $main) 入口函数驱动并等待;parallel(iterable $tasks) 并发收集结果 |
| ⏱️ 统一 sleep API | Runtime::sleep() / delay() 支持微秒级,协程环境真让出 |
| 📦 通道(Channel) | 跨平台通信,支持超时(TIMEOUT_FOREVER / TIMEOUT_NONE)、isEmpty / isFull / isTimeout |
| 🧩 defer 支持 | 按作用域隔离(协程互不串扰)、LIFO 清理、根作用域注册 shutdown |
| 🧠 上下文管理 | 基于 kode/context 的协程安全存储 |
| 🎮 Console 集成 | ConsoleRuntime 装饰器,委托给并发运行时并增强输出 |
| 🧵 Fiber 调度器 | FiberScheduler 就绪队列 + 定时器事件循环,协程假异步已修复 |
| 🔗 等待组(WaitGroup) | Runtime::waitGroup() / 全局 waitGroup() 动态派生任意数量异步任务,统一等待并分别收集结果与异常 |
| 🔁 单飞(Once) | Runtime::once() / 全局 once() 确保回调仅执行一次,并发调用者共享同一结果(含异常) |
| 🏁 竞速(race) | Runtime::race() / 全局 race() 并发执行多个任务,返回首个完成(成功或失败)的结果 |
| 📡 选择(select) | Runtime::select() / 全局 select() 等待多个通道中首个就绪者,返回其通道与数据 |
| 🚦 信号量(Semaphore) | Runtime::semaphore() / 全局 semaphore() 有界并发限流,最多允许 N 个任务同时进入临界区 |
| 🛠️ 函数助手 | 全局函数 go / parallel / run / channel / defer / delay / wait / waitGroup / once / race / select / semaphore |
🚀 快速开始
1. 安装
最低要求 PHP 8.4。
kode/context与kode/console为必需依赖(已随composer require自动安装)。可选并发能力通过扩展提供:ext-swoole、ext-swow、ext-pcntl、ext-parallel。
2. 环境检测
3. 启动协程
4. run + parallel 并发
parallel() 在具备并发能力的运行时(Fiber / Swoole / Swow / Process / Thread)真正并行;在 CLI 下顺序退化为顺序执行但保持 API 一致。
5. Channel 通信(含超时)
6. defer 清理资源
defer 按作用域隔离:协程内注册的回调只在该协程结束时执行,主流程(根作用域)注册的回调在 wait() 或脚本结束时执行,且均为后进先出(LIFO)。
7. 等待组(WaitGroup)
当任务数量在编写时不确定、或在多处动态派发时,用 WaitGroup 比一次性 parallel() 更灵活。它在内部用完成通道阻塞等待,单个任务失败不会中断其余任务,并分别收集结果与异常。
Fiber / CLI 运行时可在顶层直接使用;Swoole / Swow 等事件循环运行时请在
Runtime::run()作用域内使用(与channel/parallel一致)。
8. 单飞(Once)与通道竞争(race / select)
Once 保证回调仅执行一次,多个并发调用者共享同一次执行的结果(或异常),适合缓存一次性初始化、防止重复副作用。
race() 并发执行多个任务,返回第一个完成(无论成功或失败)的结果;其余任务继续在后台运行但结果被丢弃。若胜出任务抛异常,则向上传播。
select() 等待多个通道中第一个就绪者,返回其通道与数据,格式为 ['channel' => ChannelInterface, 'value' => mixed]。
与
WaitGroup/channel一致:Fiber / CLI 可在顶层直接使用;Swoole / Swow 等事件循环运行时请在Runtime::run()作用域内使用。
8.1 信号量(Semaphore)并发限流
semaphore(int $permits) 创建持有 N 个「许可」的信号量,任意时刻最多 N 个任务进入临界区;其余调用者阻塞等待,许可释放后方才继续。适合限制对下游服务 / 数据库的连接并发数,防止被打爆。
acquire() / release() 可手动控制许可;run($task) 等价于「acquire → 执行 → release(finally 中释放,异常不泄漏许可)」;available() / capacity() 查看当前 / 总许可数。
9. 多进程支持
子进程通过退出码返回状态:正常结束 0,任务抛异常则以 1 反馈给父进程,并把异常原文写到 stderr(与父进程共用同一错误流,不会无声失败)。
回收由调用方负责:fork() 拿到 PID 后请自行 pcntl_waitpid($pid, $status),否则子进程退出后以僵尸态驻留。Runtime::wait() 只驱动协程,不回收进程——它会从别处取走子进程状态,导致你再也读不到退出码。
子进程不会重放父进程的收尾:子进程是父进程的内存镜像,exit() 会照常触发 shutdown 链。本包在子进程侧丢弃继承来的 defer 作用域与 FiberScheduler 全局实例,因此父进程注册的 defer()、父进程未跑完的协程都不会在子进程里多做一遍。第三方通过 register_shutdown_function() 注册的收尾无法撤销,fork 前请自行确认其幂等。
10. Console 命令
ConsoleRuntime现在是装饰器:它内部委托给RuntimeAdapterFactory::createConcurrent()选择的并发运行时,只增强控制台输出,不再因为安装了kode/console就把运行时降级为同步。
🏃 常驻进程语义(v3.5.0)
HTTP worker / queue consumer 这类「一个进程服务很多次请求」的形态下,运行时适配器与调度器都是进程级单例,以下几条口径决定了故障会不会被看见。
无人接收的协程异常不再静默消失
async() 派发的协程抛异常时,一次 run() 只能向调用方抛出一个异常。v3.4.0 之前,其余异常在登记后直接清零(实测:3 个协程失败,调用方只得知 1 个,另外 2 个连痕迹都没有)。现在它们交给上报通道,run() 的「抛出第一个」契约保持不变:
未设置处理器时写 stderr(常驻 worker 的错误流本就进服务日志;error_log() 在 CLI 默认落 stdout,会混进响应体)。
Runtime::reset() 现在连调度器一起归零
适配器与 FiberScheduler 是同一份进程级状态的两侧。只清适配器时,上一个请求攒下的协程、定时器与积压异常会被下一次 run() 当作本轮结果抛出——表现为「请求 A 的失败算到了请求 B 头上」(已实测复现)。一次调用即彻底隔离:
Swoole 下 wait() 会真正等到协程收尾
Coroutine::create() 派发的协程一旦挂起(sleep / channel / IO),只清作用域是等不到它结束的:尾巴会漂到 Swoole 的 rshutdown 里执行(6.x 已对此发 Deprecated: swoole_event_rshutdown() 警告),调用方在 wait() 之后看到的状态就成了「还没做完」。现在 SwooleRuntime::wait() 会在主流程(getCid() <= 0)里驱动一次事件循环收口;已经在协程内时不嵌套驱动,交由外层 run() / 服务端循环负责。
🏷️ 版本自述(v3.6.0)
Runtime::VERSION 常量与 Runtime::version() 暴露本包版本,用于诊断输出与运行时核对:
composer.json 的 version 字段是 composer 侧的权威值,类常量是它的交叉核对副本——
tests/VersionGuardTest.php 在两者不一致时直接失败,杜绝「tag 打了、常量忘改」的漂移。
🧱 架构设计
适配器 + 抽象基类 + 装饰器
核心类
| 类名 | 说明 |
|---|---|
Runtime |
静态门面,提供全局访问点与自动探测 |
RuntimeInterface |
运行时接口契约(含 run / parallel 等新能力) |
RuntimeEnvironment |
运行环境枚举(类型安全、可用性检测、自动降级) |
RuntimeAdapterFactory |
适配器工厂,createConcurrent() 自动探测 |
AbstractRuntime |
抽象基类,统一 defer 作用域语义与通用能力 |
FiberScheduler |
PHP Fiber 协作式调度器(就绪队列 + 定时器) |
FiberRuntime |
PHP Fiber 适配器(驱动 FiberScheduler) |
SwooleRuntime |
Swoole 协程适配器 |
SwowRuntime |
Swow 协程适配器 |
ProcessRuntime |
多进程适配器(pcntl_fork + socket_pair 回收结果) |
ThreadRuntime |
多线程适配器(ext-parallel) |
ConsoleRuntime |
Console 装饰器,委托并发运行时 + 输出增强 |
CliRuntime |
CLI 同步执行适配器(顺序退化) |
RuntimeCommand |
Console 命令基类 |
WaitGroup |
等待组(动态派生异步任务、统一等待并收集结果与异常) |
Once |
单飞原语(回调仅执行一次,并发调用者共享结果) |
Semaphore |
信号量(有界并发限流,最多 N 个任务同时进入临界区) |
functions.php |
全局函数助手(composer files autoload) |
🔄 API 参考
Runtime 门面
RuntimeEnvironment 枚举
RuntimeAdapterFactory
FiberScheduler(Fiber 模式事件循环)
全局函数助手(functions.php)
RuntimeCommand 基类
WaitGroup 等待组
与
parallel()的区别:parallel()需一次性传入任务集合,且不区分「正常结果」与「任务异常」;WaitGroup可在任意位置动态派生任务,并独立收集结果与异常。
Once 单飞
Once内部使用容量为 1 的通道作为二元信号量,串行化「是否已完成」的判定与执行,保证在 Fiber / Swoole / Swow 等协作式或抢占式并发下都只执行一次。
Semaphore 信号量
Semaphore内部用容量为许可数的通道充当「许可池」,acquire()取走令牌、release()归还令牌;令牌耗尽时阻塞直至被释放,在 Fiber / Swoole / Swow 等并发下都能正确让出执行权。
🧪 Channel 接口
🧪 兼容性
| 运行环境 | 支持 | 说明 |
|---|---|---|
| Swoole | ✅ | v4.8+,需启用协程 |
| Swow | ✅ | v1.5+ |
| PHP Fiber | ✅ | PHP 8.4+ 原生 Fiber + 内置 FiberScheduler |
| Console | ✅ | 装饰器模式,委托底层并发运行时(依赖 kode/console ^4.0) |
| 多进程 | ✅ | 基于 PCNTL(ext-pcntl) |
| 多线程 | ⚠️ | 需 ext-parallel(ZTS 版本 PHP) |
| CLI | ✅ | 同步顺序执行,API 完全兼容 |
多线程已从已废弃的
pthreads迁移到官方维护的ext-parallel。
🧪 测试
测试覆盖
- ✅ Runtime 门面测试
- ✅ RuntimeEnvironment 枚举测试
- ✅ RuntimeAdapterFactory 工厂测试
- ✅ FiberRuntime + FiberScheduler 调度测试
- ✅ ProcessRuntime 适配器测试(含子进程异常传播)
- ✅ ThreadRuntime 适配器测试(
ext-parallel缺省跳过) - ✅ Channel 接口测试(含超时)
- ✅ CliRuntime 同步测试
- ✅ 全局函数助手测试
- ✅ RuntimeCommand 命令基类测试
- ✅ WaitGroup 等待组测试(结果收集、异常隔离、并发、CLI 确定性)
- ✅ Once 单飞测试(仅执行一次、并发共享、异常缓存、reset、CLI 顶层)
- ✅ race / select 竞争原语测试(最快胜出、异常传播、首个就绪通道、全局函数助手)
🛡️ 特性
- 类型安全:PHP 8.4+ 严格类型、enum、
#[\Override]、typed class constants、readonly - 真异步:Fiber 模式内置事件循环,
sleep/Channel阻塞真正让出,无忙等 - 内存管理:自动清理协程栈与作用域回调
- 异常处理:协程/子进程异常统一捕获并向上传播
- 协程安全:基于
kode/context的上下文隔离 - API 一致:同步(CLI)与并发环境共享同一套抽象,可无缝切换
📁 目录结构
🙌 贡献
欢迎提交 PR 和 Issue!
请遵循 PSR-12 编码规范,编写单元测试。
📄 许可证
Apache License 2.0
kode/runtime—— 让 PHP 在任何运行时都如丝般顺滑 🚀