PHP8.6 更新了什么?
分享 通用
wolfcode 开发者 · 6小时前
分享 收藏 评论
共 0 个评论
登录后评论
作者 🐼

wolfcode

人生一场虚空大梦,韶华白首,不过转瞬。惟有BUG恒在,往复循环,不曾更改。

# PHP 8.6 特性和功能提前预览 PHP 的年度大版本即将到来—— **PHP 8.6 正式版将于 2026年11月19号发布**。 目前它已经进入 Beta 测试阶段;9 月 22 号将执行功能冻结,两天后发布第一个 RC 候选版本。 ## 核心新特性预览 ### 1. 部分函数应用(Partial Function Application, PFA) 部分函数应用允许预先填充一部分函数参数,返回一个接收剩余参数的闭包。`?` 代表后续传入单个参数占位符;`...` 代表剩余全部参数。 ```php $makeSlug = str_replace(' ', '-', ?); $makeSlug('Hello World'); // Hello-World $titles = array_map(strtolower(?), $titles); ``` - 生成的闭包会完整保留原函数的参数名、类型声明与默认值。 - 预先传入的参数在生成偏函数时求值,而不是调用闭包的时候才求值。 - **配套规定**:每一个 `?` 占位符,在生成的闭包上都会成为必传参数,即便原函数的该参数是可选参数。 - *注:该提案旧版本 2021 年被否决;第二版 RFC 以 33 票赞成、0 票反对获得通过。* ### 2. clamp() 函数族 新增 `clamp()`:如果传入值落在最小 / 最大区间内,则直接返回原值;超出边界则返回距离最近的边界值。 ```php clamp(10, min: 0, max: 100); // 10 clamp(101, min: 0, max: 100); // 100 clamp(-1, min: 0, max: 100); // 0 ``` - 支持所有可比较类型,包含字符串、DateTime 对象。 - 如果传入的最小值大于最大值,会抛出 ValueError。 - 该函数用来替代广为使用但容易写反的写法:`min(max($value, $min), $max)`。 ### 3. Duration 时间时长类 PHP 8.6 新增 `Time\Duration`,这是一个 `final readonly` 类,用于表示秒表式时间长度,支持纳秒精度。提供各时间单位的工厂方法、算术运算方法,同时支持比较运算符。 ```php use Time\Duration; $oneSecond = Duration::fromSeconds(1); $halfSecond = $oneSecond->divideBy(2); $total = $oneSecond->add($halfSecond); $delay = Duration::fromMilliseconds(100)->multiplyBy(2 ** $attempt); $total > $delay; // 可直接使用比较运算符 ``` - 也可以通过 ISO 8601 时长字符串构建实例。 - 该类作为标准类型,供内核与新的轮询 API 接收使用,替代松散的整数、浮点数时间值。 ### 4. 只读属性支持默认值 PHP 8.6 起,`readonly` 属性可以设置默认值。8.6 版本之前,这么写属于编译错误;这让实现 PHP 8.4 只读接口属性时,写固定默认值非常别扭。 ```php final readonly class CreateBooksTable implements Migration { public string $name = '2026_01_01_create_books_table'; } ``` - RFC 仅移除语法限制;readonly 语义不变,初始化之后依旧不能重新赋值。 ### 5. 函数参数直接书写文档注释 现在可以直接给参数写文档注释,`ReflectionParameter::getDocComment()` 可以读取该注释。不再需要在函数上方的 `@param` 标签重复写参数名称。 ```php function search( /** Terms to search for in the database */ string $query, /** Maximum number of entries to return */ int $limit = 10, ): array { // ... } ``` - 静态分析工具与 IDE 可以直接读取参数上的注释。 ### 6. Polling(轮询)API 全新命名空间 `Io\Poll`,为 PHP 提供统一封装的 IO 多路复用接口:Linux 下 epoll、BSD/macOS 下 kqueue、Solaris event ports、Windows WSAPoll。对于用户态实现事件循环、异步运行时的开发者,可以用来替代旧的 `stream_select()`。 ```php use Io\Poll\{Context, Event, StreamPollHandle}; $poll = new Context(); $server = stream_socket_server('tcp://0.0.0.0:8080'); stream_set_blocking($server, false); $poll->add(new StreamPollHandle($server), [Event::Read], ['type' => 'server']); while (true) { foreach ($poll->wait(1) as $watcher) { if ($watcher->hasTriggered(Event::Read)) { // accept the connection } } } ``` - 该 API 首要目标服务 PHP 内部(例如信号处理、FPM 改进);其次供用户态异步框架使用。 ### 7. SortDirection 枚举 内置全局枚举 `SortDirection`,包含 `Ascending`(升序)、`Descending`(降序)两个 case。 ```php $query->orderBy('created_at', SortDirection::Descending); ``` - 目的是提供统一标准类型,避免各个类库各自定义排序枚举,查询构建器是典型使用场景。 ### 8. 流(Stream)统一错误处理模型 流增加统一错误模型。新增 `error_mode` 上下文选项,可选:警告、抛出异常、静默;`stream_last_errors()` 返回结构化 `StreamError` 对象,获取上一次操作的错误。 ```php $context = stream_context_create([ 'stream' => ['error_mode' => StreamErrorMode::Exception], ]); try { $stream = fopen('/nonexistent/file.txt', 'r', false, $context); } catch (StreamException $e) { foreach ($e->getErrors() as $error) { echo $error->code->name . ': ' . $error->message; } } ``` - `StreamErrorCode` 枚举定义超过 50 个语义化错误码。 ### 9. URI 扩展增强(PHP 8.5 延续改进) PHP 8.5 引入的 URI 扩展,新增 Builder 构建器类。无需创建大量中间对象,即可组装 URI。 ```php $uri = new Uri\Rfc3986\UriBuilder() ->setScheme('https') ->setHost('example.com') ->setPath('/foo/bar') ->build(); ``` ### 10. Session 会话安全默认值变更 全新安装环境下,php.ini 三个 session 配置项更新默认值: | 配置项 | 旧默认值 | 新默认值 | | --- | --- | --- | | `session.use_strict_mode` | `0` | `1` | | `session.cookie_httponly` | `0` | `1` | | `session.cookie_samesite` | 未设置 | `Lax` | --- > **结语**:PHP 8.6 在发布前一定还会有变化,但可以预知的是会带给开发者更多惊喜。