PHP8和PHP7区别及主要更新

2026-06-16 17:17:49 1079

PHP 8 的发布是 PHP 发展史上的一个重要里程碑。与 PHP 7.4 相比,PHP 8 不仅仅是一个常规的版本迭代,它在性能、类型安全、代码简洁度以及开发体验上都带来了质的飞跃。

以下是 PHP 8 与 PHP 7.4 之间最核心的区别和主要更新点:


1. JIT (Just In Time) 编译器

这是 PHP 8 最具标志性的底层更新。JIT 编译器将 PHP 代码在运行时直接编译为机器码,而不是像以前那样只编译为 Zend 虚拟机操作码 (Opcodes)。

  • PHP 7.4:只有 Opcache,代码执行仍需经过 Zend 引擎的解释。

  • PHP 8:引入 JIT。对于 I/O 密集型的常规 Web 应用(如查询数据库、渲染模板),性能提升可能在 5%-10% 左右;但对于 计算密集型任务(如图像处理、复杂数学运算、大型数组遍历),性能提升可达 200% 甚至更高。

2. 联合类型 (Union Types)

PHP 8 允许在类型声明中指定多个类型,极大地增强了代码的表达能力和类型安全。

  • PHP 7.4:只能通过 PHPDoc 注释来暗示,或者使用特殊的 ?Type (Nullable) 语法,无法表达 intstring

// PHP 7.4 只能这样写,且缺乏强制约束
/** @param int|float $number */
function processNumber($number) { ... }

// PHP 8
function processNumber(int|float $number): int|float {
    return $number;
}

3. 命名参数 (Named Arguments)

允许开发者在调用函数或方法时,通过参数名称来传递值,而无需关心参数的顺序。这大大提高了代码的可读性,尤其是在处理具有多个可选参数的函数时。

  • PHP 7.4:必须严格按照参数顺序传递,如果想跳过前面的可选参数,必须显式传递 null 或默认值。

// PHP 7.4
htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);

// PHP 8
htmlspecialchars($string, double_encode: false); // 其他参数自动使用默认值

4. Nullsafe 运算符 (?->)

这是解决 "Null 指针异常" 的终极语法糖。当你在调用链中不确定某个对象是否为 null 时,可以使用 ?->。如果链中任何一个环节为 null,整个表达式会立即返回 null,而不会抛出致命错误。

  • PHP 7.4:需要写冗长的 if 检查或使用 ??

// PHP 7.4
$country = null;
if ($session !== null) {
    $user = $session->user;
    if ($user !== null) {
        $address = $user->getAddress();
        if ($address !== null) {
            $country = $address->country;
        }
    }
}

// PHP 8
$country = $session?->user?->getAddress()?->country;

5. Match 表达式

match 可以看作是 switch 的现代化、严格化替代品。它支持返回值、使用严格比较 (===),并且不需要 break 语句。

  • PHP 7.4switch 使用松散比较 (==),容易引发 bug,且代码冗长。

// PHP 7.4
switch (8.0) {
    case '8.0':
        $result = "Oh no!";
        break;
    case 8.0:
        $result = "This is what I expected";
        break;
}

// PHP 8
$result = match (8.0) {
    '8.0' => "Oh no!",
    8.0 => "This is what I expected", // 严格匹配,会命中这一项
};


6. 构造函数属性提升 (Constructor Property Promotion)

这是一个极受欢迎的语法糖,可以大幅减少定义值对象 (Value Objects) 或 DTO (数据传输对象) 时的样板代码。

  • PHP 7.4:需要声明属性,然后在构造函数中手动赋值。

// PHP 7.4
class Point {
    public float $x;
    public float $y;
    public float $z;

    public function __construct(float $x = 0.0, float $y = 0.0, float $z = 0.0) {
        $this->x = $x;
        $this->y = $y;
        $this->z = $z;
    }
}

// PHP 8
class Point {
    public function __construct(
        public float $x = 0.0,
        public float $y = 0.0,
        public float $z = 0.0,
    ) {}
}

7. Attributes (注解/属性)

PHP 8 引入了原生的 Attributes(使用 #[...] 语法),用于替代传统的 PHPDoc 注释来存储元数据。这使得框架(如 Laravel, Symfony)可以更安全、更结构化地读取类、方法或属性的配置。

  • PHP 7.4:只能使用 /** @Annotation */ 形式的注释,需要通过正则或反射去解析字符串,容易出错且性能较差。

  • PHP 8

#[Attribute]
class Route {
    public function __construct(public string $path) {}
}

#[Route('/api/users')]
class UserController { ... }

8. 更严格的错误处理和类型一致性

PHP 8 修复了许多 PHP 7 中反直觉的行为,使语言更加严谨:

  • 内部函数类型错误:在 PHP 7.4 中,向内部函数传递错误类型的参数通常只会产生 Warning 并返回 null;在 PHP 8 中,这会直接抛出 TypeError 异常,促使开发者尽早发现 bug。

  • 字符串与数字的比较:PHP 7 中,0 == "abc" 会返回 true(因为 "abc" 被静默转换为 0)。PHP 8 中,数字与非数字字符串的比较将不再静默转换,而是抛出 TypeError 或返回 false,逻辑更符合人类直觉。

  • throw 成为表达式:现在可以在箭头函数、三元运算符或 match 中直接使用 throw,例如:$value = $nullableValue ?? throw new Exception('Value is required');

9. 移除的废弃特性

为了保证语言的现代化,PHP 8 果断移除了一些在 PHP 7.4 中已被标记为废弃的功能,包括:

  • create_function() (应使用匿名函数替代)

  • each() 函数

  • 未加括号的动态变量 (如 $$foo['bar']['baz'],现在必须写成 ${$foo['bar']['baz']})

  • 魔术引号 (Magic Quotes) 的相关残余


总结:为什么要从 PHP 7.4 升级到 PHP 8?

  1. 开发效率大幅提升:命名参数、Nullsafe 运算符、构造函数属性提升和 match 表达式,让代码行数减少,可读性显著增强。

  2. 代码更加健壮:联合类型、Attributes 以及更严格的类型检查,将大量运行时错误提前到了静态分析阶段或开发阶段。

  3. 性能天花板被打破:JIT 编译器为 PHP 打开了处理复杂计算任务的大门,同时常规的 Opcache 优化也让 Web 响应更快。

注:虽然 PHP 8.0 奠定了基础,但截至当前(2026年),PHP 社区已经广泛使用 PHP 8.2/8.3/8.4,它们在此基础上进一步引入了如 readonly 类、枚举 (Enums)、类型化常量等更强大的特性。但就 "7.4 到 8" 的跨越而言,上述特性是最核心的分水岭。


提交成功!非常感谢您的反馈,我们会继续努力做到更好!

这条文档是否有帮助解决问题?

非常抱歉未能帮助到您。为了给您提供更好的服务,我们很需要您进一步的反馈信息:

在文档使用中是否遇到以下问题: