首页 / PHP 入门教程 / PHP 8 新特性详解

PHP 入门教程

PHP 8 新特性详解

本教程共 65 篇 · 第 46 篇 · 更新于 2026-07-24 · 约 13 分钟阅读

PHPPHP8JIT命名参数联合类型match表达式枚举

46. PHP 8 新特性详解

本节目标:全面了解 PHP 8.x 系列的核心新特性,能够在实际开发中运用 JIT、命名参数、match、枚举等现代语法。

PHP 8 于 2020 年发布,带来了大量颠覆性的语法改进。本节基于 PHP 8.0 至 8.5 的关键特性进行讲解。注意:部分示例(如枚举、readonly、Fiber 等)需要 PHP 8.1+,建议以 PHP 8.2+ 为最低版本。


1. JIT 即时编译

JIT(Just In Time)是 PHP 8 最底层的性能提升。它将热点代码编译为机器码执行,在计算密集型任务(如图像处理、大数据运算)中效果显著。

; php.ini 中开启 JIT
opcache.enable=1
opcache.jit_buffer_size=100M
opcache.jit=tracing

日常 Web 开发中,IO 操作(数据库、文件)占大头,JIT 的提升可能不明显。但了解它的存在,有助于你在性能调优时多一个选项。

Note

JIT 需要 OpCache 扩展支持。大部分生产环境已默认启用 OpCache,只需配置 JIT 参数即可。


2. 命名参数

以前调用函数必须按顺序传参。PHP 8 支持按参数名传值,顺序可以打乱,可读性大幅提升。

<?php
function createUser(string $name, string $email, int $age = 18, bool $active = true): void
{
    echo "{$name} / {$email}\n";
}

// 传统方式:必须按顺序
createUser('张三', 'zhang@example.com', 25, true);

// PHP 8 命名参数:顺序任意,可跳过默认值
createUser(
    email: 'zhang@example.com',
    name: '张三',
    age: 25
);
Tip

命名参数与位置参数可以混用,但位置参数必须在前。


3. 联合类型

一个参数或返回值可以是多种类型之一,用 | 连接。

<?php
function parseId(int|string $id): int
{
    return (int) $id;
}

echo parseId(42);      // 42
echo parseId('007');   // 7

可空类型也有了更简洁的写法:

<?php
// PHP 7 写法
function findUser(int $id): ?User {}

// PHP 8 等价写法
function findUser(int $id): User|null {}
Note

false 也可以作为类型的一部分,例如 int|false,常用于表示查找失败。


4. match 表达式

matchswitch 的现代化替代品。它更像表达式,可以直接赋值,且默认使用严格比较(===)。

<?php
$status = 200;

// 传统 switch
$message = '';
switch ($status) {
    case 200:
        $message = '成功';
        break;
    case 404:
        $message = '未找到';
        break;
    default:
        $message = '未知状态';
}

// PHP 8 match
$message = match ($status) {
    200 => '成功',
    404 => '未找到',
    default => '未知状态',
};
Tip

match 不需要 break,也没有穿透(fall-through)行为。每条分支只能写单个表达式,多行逻辑需提取为函数。


5. 属性(注解)

PHP 8.0 引入 Attributes(属性/注解),用 #[...] 语法为类、方法、参数添加元数据。

<?php
#[Attribute]
class Route {
    public function __construct(public string $path, public string $method = 'GET') {}
}

class UserController {
    #[Route('/users', 'GET')]
    public function index(): array
    {
        return ['list' => []];
    }

    #[Route('/users', 'POST')]
    public function store(): array
    {
        return ['created' => true];
    }
}

// 读取属性
$ref = new ReflectionClass(UserController::class);
foreach ($ref->getMethods() as $method) {
    foreach ($method->getAttributes(Route::class) as $attr) {
        $route = $attr->newInstance();
        echo "{$route->method} {$route->path}\n";
    }
}
Note

属性本身不会执行任何逻辑,需要配合反射读取后手动处理。主流框架(如 Symfony、Laravel)已广泛使用。


6. 构造函数属性提升

在构造函数中直接声明属性并赋值,告别冗余的样板代码。

<?php
// PHP 7 写法
class User {
    public string $name;
    public string $email;

    public function __construct(string $name, string $email) {
        $this->name = $name;
        $this->email = $email;
    }
}

// PHP 8 写法
class User {
    public function __construct(
        public string $name,
        public string $email
    ) {}
}

$user = new User('张三', 'zhang@example.com');
echo $user->name;
Tip

可配合访问修饰符 publicprotectedprivate 使用,只写参数不写修饰符则不会提升为属性。


7. Nullsafe 运算符 ?->

链式调用时,如果中间某个对象为 null,传统写法需要层层判断。PHP 8 的 ?-> 会在遇到 null 时安全返回 null,不再报错。

<?php
$order = getOrder(); // 可能返回 null

// PHP 7 写法
$country = null;
if ($order !== null && $order->address !== null) {
    $country = $order->address->country;
}

// PHP 8 写法
$country = $order?->address?->country;
Note

?-> 只会在左侧为 null 时短路返回 null。如果左侧属性存在但值为 null,后续调用仍会执行。


8. 字符串辅助函数

PHP 8.0 新增了三个常用的字符串判断函数,告别冗长的 strpos 判断。

<?php
$str = 'Hello World';

// 是否包含子串
var_dump(str_contains($str, 'World')); // true

// 是否以某子串开头
var_dump(str_starts_with($str, 'Hello')); // true

// 是否以某子串结尾
var_dump(str_ends_with($str, '!')); // false
Tip

这些函数大小写敏感。如需忽略大小写,先用 strtolower() 转换再判断。


9. 枚举 enum

PHP 8.1 引入枚举,让一组固定取值的定义更加类型安全。

<?php
enum Status: string {
    case Draft = 'draft';
    case Published = 'published';
    case Archived = 'archived';
}

function setStatus(Status $status): void
{
    echo "当前状态:{$status->value}\n";
}

setStatus(Status::Published);

枚举还可以定义方法:

<?php
enum Priority: int {
    case Low = 1;
    case Medium = 2;
    case High = 3;

    public function label(): string {
        return match($this) {
            self::Low => '低',
            self::Medium => '中',
            self::High => '高',
        };
    }
}

echo Priority::High->label(); // 高
Note

enum 分两种:纯枚举(Pure Enum)不关联值,Backed Enum 可关联 intstring。上例是 Backed Enum。


10. 其他实用新特性

特性说明版本
str_contains 系列字符串包含判断8.0
throw 表达式throw 可作为表达式使用8.0
mixed 类型显式声明任意类型8.0
static 返回类型支持返回 static8.0
readonly 属性只读属性,初始化后不可修改8.1
纤维(Fiber)协程支持,用于异步编程8.1
类常量可见性private const FOO = 1;8.1
<?php
// throw 表达式示例
$value = $config['key'] ?? throw new InvalidArgumentException('缺少配置');

小结

PHP 8 让代码更简洁、更安全、更具表达力。match、属性提升、?-> 等特性减少了大量样板代码,枚举和联合类型让类型系统更完善。建议所有新项目以 PHP 8.1+ 为最低版本。


来源:参考了 PHP 官方文档(PHP 8.0-8.5)、php-the-right-way,改写后所得。