2026 年 11 月 5 日,PHP 官方发布了 PHP 8.6.0 RC5——8.6 发布周期的最后一个候选版。按官网公告,下一个版本就是正式版 PHP 8.6.0,计划于 11 月 19 日发布。本文全部信息取自 php.net 官方公告、发布周期 Wiki 以及 RC5 标签下的 NEWS / UPGRADING 文件,帮你一次看清:这个版本改了什么、8.6 有哪些新东西、从 8.5 升级要提前排查什么。

官方公告说了什么

公告标题是 PHP 8.6.0 RC5 available for testing,措辞与以往 RC 公告一致,重点并不长:

The next release will be the first GA release, PHP 8.6.0, planned for 19 November 2026.
Please DO NOT use this version in production, it is an early test version.
—— php.net,05 Nov 2026
项目内容
版本PHP 8.6.0 RC5(8.6 周期最后一个候选版)
发布日期2026 年 11 月 5 日
下一版本首个 GA 正式版 PHP 8.6.0,计划 2026 年 11 月 19 日
源码下载https://downloads.php.net/~svpernova09/
升级资料RC5 标签的 NEWS 与 UPGRADING(也在源码包中)
问题反馈php-src 的 GitHub Issues(bug report 模板)
签名校验release manifest 或预发布构建页
⚠️
不要上生产
官方原文加粗强调:Please DO NOT use this version in production。RC5 只用于兼容性测试、扩展回归、CI 试跑,正式部署请等 11 月 19 日的 GA。

一个容易看懵的细节:为什么 RC5 叫「第四个」候选版?

公告原文写的是 the fourth release candidate of PHP 8.6.0, RC5。这不是笔误:按发布周期 Wiki,9 月 24 日的 RC1 因打包失误被跳过,官方直接发布了 RC2,并在公告里专门说明「It is not a typo」。所以实际发布的候选版依次是 RC2、RC3、RC4、RC5,RC5 恰好是第四个。

8.6 发布周期:从 Alpha 到 GA

PHP 8.6 发布时间线(2026)
7/02 Alpha1 → 7/16 Alpha2 → 7/30 Alpha3(新特性密集落地)
↓
8/13 Beta1(特性冻结)→ 8/27 Beta2 → 9/10 Beta3
↓
9/24 RC2(RC1 跳过)→ 10/08 RC3 → 10/21 RC4
↓
11/05 RC5(收官候选版)→ 11/19 GA 正式版

本届发布经理是 Daniel Scherzer(资深)、Matteo Beccati 与 Joe Ferguson。节奏是「周二打 tag、周四发公告」,预发布阶段约 5 个月;从 Beta1 起特性冻结,因此 RC 阶段几乎不再加新功能,全部精力放在稳定性与安全性上。

💡 小技巧:Wiki 时间表会随开发进度增删版本,引用日期时以 php.net 新闻归档里的实际公告为准,别只抄计划表。

RC5 修了什么:一次以 JIT 和内存安全为主的收尾

翻看 RC5 的 NEWS,条目覆盖 34 个模块、上百条记录,且几乎全是 Fixed。按模块分布看,重心非常清楚:

模块条目量级代表性修复
Opcache / JIT约 28 条(最多)tracing JIT 整数溢出返回类型错误、ASSIGN_DIM_OP 释放后使用、AArch64 立即数编码、函数 JIT 异常范围检查、preload 重启后不再重编译等
Core11 条部分函数应用中命名参数的越界写、AST 打印丢失 final/readonly 修饰符、trait 常量表达式中静态方法的可见性绕过
Phar9 条zip-based phar 别名长度导致的堆越界读、rename() 与 copy() 的 UAF / double free、超大 tar 元数据耗尽内存
Standard / Streams7 + 4 条Io\Poll kqueue 后端内存泄漏、HTTP wrapper 的 dechunk filter 泄漏、ftp:// 响应解析越界读
FPM5 条pool 名超长时 worker 日志崩溃与栈内存泄露、worker stdio 管道 fd 重复关闭、状态页内存泄漏
OpenSSL / 其它4 条 + 零散TLS PSK 回调堆缓冲区溢出、TLS session remove callback 的 UAF、OpenSSL 4.1 构建修复

值得单独标记的三条安全性变更

  • URI:升级到 uriparser 1.0.3,对应 CVE-2026-48841——RC5 中唯一明确标注 CVE 的依赖升级。
  • Session:校验整个 session ID,不再遇到第一个 NUL 字节就停止,堵住 ID 截断类绕过。
  • Sodium:sodium_crypto_xof_*() 的状态改为通过对象传递,不再使用 by-ref 字符串。

此外还有几处行为收紧:Windows 配置阶段拒绝有缺陷的 libzip 1.3.1 / 1.7.0 / 1.12.0,Io\Poll 的 WSAPoll 后端不再静默丢弃非 socket 句柄(改为 ERROR_NOSUPPORT 失败),json_encode() 在键编码失败后不再继续输出。

bash 本地查看 RC5 原始资料
# 直接读官方仓库对应标签的文本
curl -sL https://raw.githubusercontent.com/php/php-src/php-8.6.0RC5/NEWS | head -80
curl -sL https://raw.githubusercontent.com/php/php-src/php-8.6.0RC5/UPGRADING | less

# 源码包编译测试(仅测试环境,勿用于生产)
wget https://downloads.php.net/~svpernova09/php-8.6.0RC5.tar.gz
tar xzf php-8.6.0RC5.tar.gz && cd php-8.6.0RC5
./configure --disable-all --enable-cli
make -j$(nproc) && make test
⚠️ 注意:上面是最小的 CLI 构建示例,实际项目请按自己的扩展清单补全 configure 参数;./configure --help 才是准确选项来源。
ℹ️
和本站此前的安全公告连起来看
10 月 21 日官方修复的两个高危 RCE(CVE-2026-109618 / CVE-2026-109619)已在 RC4 中同步合入,本站另有专文介绍:PHP 安全公告解读。RC5 则主要是在此基础上继续收敛 JIT、Phar 与流的内存问题。

8.6 到底带来什么:新特性速览

RC5 本身不加特性,但要判断值不值得升级,得看整个 8.6 周期积累了什么。以下摘自官方 UPGRADING 的 New Features / New Functions:

类别新特性一句话说明
语言部分函数应用(PFA)预填部分参数生成新可调用体,减少手写闭包
语言readonly 属性可声明默认值、#[\Override] 支持类常量不可变对象写法更自然
标准库clamp()把值限制在区间内,越界返回最近边界
日期 / IOTime\Duration、Io\Poll\* 轮询 API时间长度与事件轮询有了原生抽象
流stream errors API(StreamException、stream_last_errors() 等)流错误可结构化读取与清理
安全 / TLSTLS 会话恢复、外部 PSK、TLS 1.3 0-RTT 早期数据流上下文可复用会话、降低握手开销
URI / ZipUri\Rfc3986\UriBuilder、ZipArchive::openString()/closeString()URI 构造与内存态 zip 处理
性能printf() 编译为字符串插值、array_map() 编译为 foreach减少函数调用与中间闭包开销
php 8.6 新增/放宽写法示例
<?php
// clamp():把值限制在 0~100
$score = clamp(128, 0, 100);   // 100

// readonly 属性现在可以带默认值
final class Config {
    public readonly int $timeout = 30;
}

// trim() 默认裁剪字符新增了 \f(换页符)——注意这是行为变化
$text = trim("\fhello\f");     // "hello"

从 8.5 升级前,先核对这份清单

比起「有什么新功能」,升级时更要紧的是「哪里会炸」。UPGRADING 里最需要提前处理的是以下四类。

1. Session 三个默认值变了(优先级最高)

配置项8.5 默认8.6 默认可能影响
session.use_strict_mode01自定义 handler 必须实现 validateId()/create_sid(),否则外部传入的未初始化 ID 会被拒绝
session.cookie_httponly01JS 不再能通过 document.cookie 读到会话 cookie
session.cookie_samesite未设置Lax跨站 POST 不再携带会话 cookie,需显式设 None 且开启 cookie_secure
ini php.ini(确有旧行为依赖时才回退)
; 8.6 默认值已更安全,以下仅为兼容旧系统的临时回退示例
session.use_strict_mode = 1
session.cookie_httponly = 1
session.cookie_samesite = Lax

另外,session_encode() 对空会话从返回 false 改为返回空字符串;配合 session.lazy_write 时,空会话可能改走 updateTimestamp() 而不是 write(),自定义 handler 的清理逻辑要同步迁移。

2. 大量「warning / false / 静默截断」改成抛异常

8.6 把一批非法输入统一改成 ValueError / TypeError。旧代码里只判断返回值、依赖警告或隐式转换的逻辑最容易出问题:

  • 含 NUL 字节的参数:getenv()、putenv()、parse_str()、proc_open()、dl()、openlog()、文件路径类函数等;
  • preg_grep() 在 PCRE 执行出错时返回 false,不再是部分结果数组;
  • fclose()、file_put_contents()、copy() 在 flush/close 失败时返回 false,此前会被静默忽略;
  • ZipArchive 序列化 / 反序列化现在抛异常;GMP 位移与幂运算右操作数越界抛 ValueError。

3. 弃用清单很长,尽早扫一遍 E_DEPRECATED

php 8.6 常见弃用项(节选)
// 类型/字符串老别名
is_double() / is_long() / is_integer() / doubleval() / metaphone() / strcoll()
// SPL 与哈希
spl_classes() / spl_object_hash() / SplFileObject::fgetcsv() 等 CSV 方法
// 语言用法
finally 中 return / __construct() 与 __destruct() 返回值
"namespace" 作类常量名 / "let" "is" "_" 作名称或别名 / define() 第 3 个参数
// 其它
Mbregex(Oniguruma 已停止维护)/ mysqli_get_charset() / SORT_LOCALE_STRING
php://filter 超过 16 个 filter 且未配置 filter.max_filter_count

4. 会改变输出或快照的语义变化

  • trim()/ltrim()/rtrim() 默认裁剪字符新增 \f;
  • unpack() 把格式码后的 < / > 当作大小端修饰符,不再当作键名首字符;
  • array_intersect() 的字符串转换时机变化,会影响 __toString() 调用次数与顺序;
  • 反射输出布尔常量从 1/空串改为 true/false;ini_get_all() 新增 builtin_default_value;
  • Windows 官方构建改用 VS2026、OpenSSL 4、libxml2 2.15.3;Fileinfo 升级到 file 5.48,旧版自定义 magic database 必须重新生成。
⚠️
升级动作顺序
① staging 开启 E_ALL 并收集 E_DEPRECATED → ② 回归登录态、跨站 POST、JS 读 cookie 与自定义 session handler → ③ 审计含 NUL 字节的输入路径与依赖 false/warning 的分支 → ④ 更新对错误消息、反射输出、URI 校验顺序的断言 → ⑤ 核对 libcurl / libpq / ICU / libsodium / OpenSSL 版本门槛。

现在该做什么

角色建议
业务应用开发者把 RC5 加进 CI 的「允许失败」任务,跑全量测试并收集弃用日志;不要部署到生产
框架 / 扩展维护者重点回归 JIT/Opcache、Phar、流与 FPM 相关路径,RC5 的修复正好集中在这几块
运维 / 升级决策者以 11 月 19 日 GA 为目标做升级排期,同时留意 10 月 21 日两个高危 RCE 的修复是否已在现有分支落地

官方资料入口:

  • 新闻归档:https://www.php.net/archive/2026.php(RC5 公告与该周期全部公告)
  • 发布周期:https://wiki.php.net/todo/php86(时间表、发布经理)
  • 变更明细:https://github.com/php/php-src/blob/php-8.6.0RC5/NEWS
  • 升级说明:https://github.com/php/php-src/blob/php-8.6.0RC5/UPGRADING
  • 源码与签名:https://downloads.php.net/~svpernova09/、https://www.php.net/pre-release-builds.php

总结

PHP 8.6.0 RC5 不是「又一个小版本」,而是 8.6 周期进入收尾的信号:上百条修复集中砸在 JIT、Phar、流与 TLS 的内存安全上,特性冻结后再无新增窗口,GA 已进入两周倒计时。对开发者来说,现在最划算的动作不是尝鲜,而是拿 RC5 把测试跑一遍,把弃用与 Session 默认值问题提前消化掉,等 11 月 19 日正式版发布时就能从容升级。

候选版的意义,是让正式版少一个意外。