PHP 8.6 RC3:fiber 里的警告全部静默,这个回归修掉了
PHP 8.6.0 RC3 于 2026-10-08 发布,RC1 被跳过。RC 阶段只合入 bugfix,其中几项是回滚 8.6 自己引入的回归。最需要先看的是 fiber 内警告静默的问题。
现象:fiber 里 error_reporting() 变成 0
在 8.6 beta 与 RC2 中,如果 error_reporting 这个 INI 指令没有值,新建的 Fiber 会以 error_reporting=0 启动。fiber 内所有 warning / notice 直接消失,fiber 外的代码照常报告。
复现脚本:
echo error_reporting(), "\n";
(new Fiber(function () {
echo error_reporting(), "\n";
echo $undefined;
echo "after\n";
}))->start();
在 RC2 下用 php -n 跑:
php -n repro.php
fiber 里打印 0,$undefined 的 undefined variable 警告不出现。同样的脚本在 PHP 8.5 上,fiber 内外两次都打印 30719,并且正常发出警告。
触发条件:error_reporting 没有设置
这里容易误判:问题不是把 error_reporting 配成了 0,而是这个 INI 指令根本没有值。
没有 php.ini 时就是这种情况,包括官方 Docker 镜像和 php -n。如果本地环境用了 php.ini-development 或 php.ini-production,一般显式设了 error_reporting,反而不容易撞上。CI 容器、临时调试环境、精简镜像更常见。
影响面:fiber 事件循环上的异步代码
Revolt、AMPHP 以及其他基于 fiber 的事件循环,警告和 notice 会全部丢失。异步回调里变量名写错、数组键不存在、废弃 API 调用,都表现为“什么都没发生”,只剩业务逻辑不按预期走。
这类问题在 beta 阶段不好排查,因为错误报告被静默,日志和输出都没有线索。
修法:升级到 RC3
Gina Peter Banyard 在 RC3 修掉了这个问题(issue GH-23921)。fiber 现在以配置的错误级别启动,默认与外部一致,为 E_ALL。用 @ 包住启动 fiber 的代码,仍然不会泄漏到 fiber 体内。
正确的处理是升级到 RC3,而不是在业务代码里塞一句 error_reporting(E_ALL)。后者只是把当前进程的错误级别改掉,问题出在 fiber 启动时继承 INI 值的行为上;入口处手动设置会掩盖配置本身的问题,第三方库内部新建的 fiber 也不一定经过你的入口代码。
同批修掉的其它回归
RC3 里还有几项回滚或修正:
hrtime()回到CLOCK_MONOTONIC。此前改用 raw clock,导致某些机器上快 4%。strict_types=1的文件里,关掉array_map()的更快编译路径。- OPcache 不再把
$cond ? -0.0 : 0.0折叠成单个-0.0。 - 内置 web server 每个 HEAD 请求泄漏一个文件描述符。
- 另有一长串 PDO、OpenSSL、Intl 与内存安全修复。
时间线
- 2026-10-08:RC3
- 2026-10-22:RC4
- 2026-11-05:RC5
- 2026-11-19:GA 正式发布
升级前先跑自己的测试套件
在 8.6 beta 上跑过异步代码的,建议直接在 RC3 上重跑测试套件。之前被隐藏的警告现在会出现,fiber 相关测试突然多出一批 warning / notice 属于预期,不是新引入的故障。
8.6 GA 的内容这里不展开:partial function application、clamp()、Time\Duration、Io\Poll 轮询 API、流错误结构化 API、反射的 isReadable/isWritable、SortDirection 枚举、mysqli_quote_string、TLS session resumption,以及 session 默认值变更。RC 阶段先关注回归修复,等 11-19 正式版再整体评估。