PHP 8.5 发布:引入管道操作符、内置 URI 扩展
PHP 8.5 在 2025 年 11 月 20 日发布,PHP 8.5 是 PHP 语言的一次重大更新,新增了 URI 扩展、管道操作符,以及对克隆时修改属性的支持,PHP 官方宣称这一版本更智能、更快速,为未来而生。

URI 扩展
新的常驻 URI 扩展提供了安全解析和修改 URI、URL 的 API,遵循 RFC 3986 和 WHATWG URL 标准。
// PHP 8.4 及更早版本
$components = parse_url('https://php.net/releases/8.4/en.php');
var_dump($components['host']);
// string(7) "php.net"
// PHP 8.5
use Uri\Rfc3986\Uri;
$uri = new Uri('https://php.net/releases/8.5/en.php');
var_dump($uri->getHost());
// string(7) "php.net"
管道操作符
管道操作符允许将多个函数调用串联起来,而无需处理中间变量。它可以将许多“嵌套调用”替换成从左到右可读的链式结构。
// PHP 8.4 及更早版本
$title = ' PHP 8.5 Released ';
$slug = strtolower(
str_replace('.', '',
str_replace(' ', '-',
trim($title)
)
)
);
var_dump($slug);
// string(15) "php-85-released"
// PHP 8.5
$title = ' PHP 8.5 Released ';
$slug = $title
|> trim(...)
|> (fn($str) => str_replace(' ', '-', $str))
|> (fn($str) => str_replace('.', '', $str))
|> strtolower(...);
var_dump($slug);
// string(15) "php-85-released"
Clone With
现在可以在对象克隆时通过向 clone() 传递关联数组来更新属性。这让 readonly 类的 with-er 模式变得简单明了。
// PHP 8.4 及更早版本
readonly class Color
{
public function __construct(
public int $red,
public int $green,
public int $blue,
public int $alpha = 255,
) {}
public function withAlpha(int $alpha): self
{
$values = get_object_vars($this);
$values['alpha'] = $alpha;
return new self(...$values);
}
}
$blue = new Color(79, 91, 147);
$transparentBlue = $blue->withAlpha(128);
// PHP 8.5
readonly class Color
{
public function __construct(
public int $red,
public int $green,
public int $blue,
public int $alpha = 255,
) {}
public function withAlpha(int $alpha): self
{
return clone($this, [
'alpha' => $alpha,
]);
}
}
$blue = new Color(79, 91, 147);
$transparentBlue = $blue->withAlpha(128);
#[\NoDiscard] 属性
为函数添加 #[\NoDiscard] 属性后,PHP 会检查返回值是否被使用,若未使用则发出警告。这样可以提高 API 的安全性,避免关键返回值被忽略。
可以使用 (void) 来显式表示“我就是不使用这个结果”。
// PHP 8.4 及更早版本
function getPhpVersion(): string
{
return 'PHP 8.4';
}
getPhpVersion(); // No warning
// PHP 8.5
#[\NoDiscard]
function getPhpVersion(): string
{
return 'PHP 8.5';
}
getPhpVersion();
// Warning: The return value of function getPhpVersion() should
// either be used or intentionally ignored by casting it as (void)
常量表达式中的闭包和 First-class 可调用
静态闭包和 First-class 可调用现在可以用于常量表达式,包括属性参数、属性/参数默认值以及常量等。
// PHP 8.4 及更早版本
final class PostsController
{
#[AccessControl(
new Expression('request.user === post.getAuthor()'),
)]
public function update(
Request $request,
Post $post,
): Response {
// ...
}
}
// PHP 8.5
final class PostsController
{
#[AccessControl(static function (
Request $request,
Post $post,
): bool {
return $request->user === $post->getAuthor();
})]
public function update(
Request $request,
Post $post,
): Response {
// ...
}
}
持久化 cURL Share 句柄
与 curl_share_init() 不同,由 curl_share_init_persistent() 创建的句柄在请求结束时不会销毁。如果发现具有相同共享选项的持久化句柄,将会复用,从而避免每次初始化 cURL 句柄的开销。
// PHP 8.4 及更早版本
$sh = curl_share_init();
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);
$ch = curl_init('https://php.net/');
curl_setopt($ch, CURLOPT_SHARE, $sh);
curl_exec($ch);
// PHP 8.5
$sh = curl_share_init_persistent([
CURL_LOCK_DATA_DNS,
CURL_LOCK_DATA_CONNECT,
]);
$ch = curl_init('https://php.net/');
curl_setopt($ch, CURLOPT_SHARE, $sh);
// This may now reuse the connection from an earlier SAPI request
curl_exec($ch);
array_first() 与 array_last() 函数
array_first() 与 array_last() 分别返回数组的第一个或最后一个值。若数组为空,则返回 null(方便与 ?? 操作符组合)。
// PHP 8.4 及更早版本
$lastEvent = $events === []
? null
: $events[array_key_last($events)];
// PHP 8.5
$lastEvent = array_last($events);
PHP 8.5 可以说是更好的语法、更高的性能、更安全的类型系统。那你呢?现在还在用什么版本的 PHP?