PHP 8.5 上手:URI 扩展、|> 运算符与一批弃用变更
PHP 8.5 于 2025 年 11 月 20 日发布。
- 发布公告:
- UPGRADING:
- 迁移指南:
URI 扩展
新增内置 URI 扩展,按 RFC 3986 与 WHATWG URL 标准解析、规范化、处理 URL,底层由 uriparser 与 Lexbor 驱动。
旧写法:
$c = parse_url('https://php.net/releases/8.5/en.php');
$host = $c['host'];
新写法:
use Uri\Rfc3986\Uri;
$uri = new Uri('https://php.net/releases/8.5/en.php');
$uri->getHost();
parse_url() 返回数组、字段缺失要靠 ?? 兜底;Uri\Rfc3986\Uri 走对象接口,取值走方法。
Pipe 运算符
|> 支持从左到右链式调用,省掉中间变量:
$slug = $title
|> trim(...)
|> (fn($s) => str_replace(' ', '-', $s))
|> (fn($s) => str_replace('.', '', $s))
|> strtolower(...);
clone with
clone() 现在是函数,第二个参数接受 $withProperties 关联数组,在克隆时更新属性,readonly 类的 with-er 模式不用再手工拼数组:
return clone($this, ['alpha' => $alpha]);
PHP 8.4 及更早版本需要先 get_object_vars() 拿到属性数组,再 new self(...) 重新构造。
#[\NoDiscard]
函数返回值未被使用时发出警告,配套 (void) 强制转换表示有意忽略:
#[\NoDiscard]
function save(): bool { /* ... */ }
save(); // 警告:返回值未被使用
(void) save(); // 显式忽略
闭包与一等可调用进入常量表达式
闭包和一等可调用现在可用于常量表达式,包括属性参数、属性/参数默认值、常量与类常量。属性参数里直接写校验逻辑:
#[AccessControl(static function (Request $r, Post $p): bool {
return $r->user === $p->getAuthor();
})]
持久 cURL share handle
curl_share_init_persistent() 创建的 handle 不在请求结束时销毁,相同共享选项的 handle 可复用,避免每次请求重复初始化连接:
$sh = curl_share_init_persistent([CURL_LOCK_DATA_DNS, CURL_LOCK_DATA_CONNECT]);
array_first() / array_last()
返回数组首值/末值,空数组返回 null,方便直接和 ?? 组合:
$first = array_first($items) ?? 'default';
其他改进
- 致命错误(例如超出最大执行时间)现在带 backtrace,
fatal_error_backtraces默认值为1。 - 属性(attributes)可作用于常量。
#[\Override]可用于属性(property)。#[\Deprecated]可用于 trait 和常量。- 静态属性支持非对称可见性。
- 构造器属性提升可用
final。 - 新增
Closure::getCurrent()。 setcookie()/setrawcookie()支持"partitioned"。- 新增
get_error_handler()/get_exception_handler()。 - 新增
Dom\Element::getElementsByClassName()/insertAdjacentHTML()。 - 新增
grapheme_levenshtein()。 - 新增
#[\DelayedTargetValidation]。 php --ini输出 INI diff。- OpCache 现为非可选组件,始终包含在二进制中。
弃用与不兼容变更
- 反引号作为
shell_exec别名弃用。 - 非规范转换名
(boolean)/(integer)/(double)/(binary)弃用,改用(bool)/(int)/(float)/(string)。 disable_classesINI 移除。case语句用分号结尾弃用。null作为数组下标,或传给array_key_exists()弃用。class_alias()不再允许"array"/"callable"作为别名。__sleep/__wakeup软弃用,改用__serialize/__unserialize。NAN转其他类型发出警告。- 用
[]或list()解构非数组值(null除外)发出警告。 - float 转 int 不可表示时发出警告。