PHP 7 新特性
Type declarations, null coalescing and the spaceship from PHP 7, plus key 7.4 and 8.x additions.
Key PointsPHP 7 doubled performance and added scalar types; PHP 8 brought match, named arguments and enums.
Version timeline
| Version | Year | Highlights |
|---|---|---|
| 7.0 | 2015 | 性能翻倍、标量类型声明、??、<=>、匿名类 |
| 7.1 | 2016 | 可空类型 ?int、void、类常量可见性 |
| 7.2 | 2017 | object 类型、参数类型拓宽 |
| 7.3 | 2018 | 尾逗号、json_last_error_msg 改进 |
| 7.4 | 2019 | 箭头函数、类型化属性、数组展开、??= |
| 8.0 | 2020 | JIT、命名参数、match、构造器提升、?-> |
| 8.1 | 2021 | 枚举、只读属性、never、Fiber |
| 8.2 | 2022 | 只读类、null/false 独立类型 |
| 8.3 | 2023 | 类型化类常量、json_validate、动态属性弃用 |
Core PHP 7.0 changes
PHP
<?php
declare(strict_types=1);
// 标量类型声明 + 返回类型
function add(int $a, int $b): int {
return $a + $b;
}
echo add(1, 2), "\n";
// 空合并
$user = [];
echo ($user["name"] ?? "匿名"), "\n";
// 飞船运算符
echo 1 <=> 2, " ", 2 <=> 2, " ", 3 <=> 2, "\n";
// 常量数组
const COLORS = ["red", "green"];
echo COLORS[0], "\n";
// 匿名类
$obj = new class {
public function hi(): string {
return "匿名类";
}
};
echo $obj->hi(), "\n";
// intdiv
echo intdiv(10, 3), "\n";
// 引擎错误也能 catch 了(Throwable)
try {
intdiv(1, 0);
} catch (Throwable $e) {
echo get_class($e), "\n";
}Output
3
匿名
1 0 -1
red
匿名类
3
DivisionByZeroErrordeclare(strict_types=1) makes type declarations strict. Without it add("1", "2") is coerced silently.
Practical 7.4 additions
PHP
<?php
// 类型化属性
class Point
{
public int $x = 0;
public ?string $label = null;
}
$p = new Point();
$p->x = 5;
echo $p->x, "\n";
// 箭头函数
$double = fn($n) => $n * 2;
echo $double(4), "\n";
// 数组展开
$a = [1, 2];
$b = [3, 4];
echo implode(",", [...$a, ...$b]), "\n";
// 空合并赋值
$cache = [];
$cache["k"] ??= "默认值";
echo $cache["k"], "\n";Output
5
8
1,2,3,4
默认值Key PHP 8 features
PHP
<?php
// 命名参数
function box(int $w, int $h): int {
return $w * $h;
}
echo box(h: 3, w: 4), "\n";
// match
echo match (2) {
1 => "一",
2 => "二",
default => "其它",
}, "\n";
// 构造器属性提升
class User
{
public function __construct(
public string $name,
public int $age = 0,
) {}
}
echo (new User("Tom", 18))->name, "\n";
// 空安全运算符
$maybe = null;
echo $maybe?->name ?? "无对象", "\n";
// 枚举
enum Level: int
{
case Low = 1;
case High = 2;
}
echo Level::High->name, "\n";Output
12
二
Tom
无对象
High?-> short-circuits the whole chain when the left side is null. Any null link yields null — far cleaner than nested null checks.Upgrade notes
- Removed in 8.0 ——
each(),create_function(), stricter type checks - Behaviour change in 8.0 —— string/number comparison changed;
0 == "abc"is nowfalse - Deprecated in 8.1 —— assigning undeclared properties
- Deprecated in 8.2 —— dynamic properties and
${var}interpolation - Deprecated in 8.3 ——
get_class()without arguments
Before upgrading, run
composer outdated and a static analyser (PHPStan / Psalm). Type-related breaks dominate upgrade issues and static analysis catches them early.版本演进
| 版本 | 年份 | 主要变化 |
|---|---|---|
| 7.0 | 2015 | 性能翻倍、标量类型声明、??、<=>、匿名类 |
| 7.1 | 2016 | 可空类型 ?int、void、类常量可见性 |
| 7.2 | 2017 | object 类型、参数类型拓宽 |
| 7.3 | 2018 | 尾逗号、json_last_error_msg 改进 |
| 7.4 | 2019 | 箭头函数、类型化属性、数组展开、??= |
| 8.0 | 2020 | JIT、命名参数、match、构造器提升、?-> |
| 8.1 | 2021 | 枚举、只读属性、never、Fiber |
| 8.2 | 2022 | 只读类、null/false 独立类型 |
| 8.3 | 2023 | 类型化类常量、json_validate、动态属性弃用 |
PHP 7.0 的核心变化
PHP
<?php
declare(strict_types=1);
// 标量类型声明 + 返回类型
function add(int $a, int $b): int {
return $a + $b;
}
echo add(1, 2), "\n";
// 空合并
$user = [];
echo ($user["name"] ?? "匿名"), "\n";
// 飞船运算符
echo 1 <=> 2, " ", 2 <=> 2, " ", 3 <=> 2, "\n";
// 常量数组
const COLORS = ["red", "green"];
echo COLORS[0], "\n";
// 匿名类
$obj = new class {
public function hi(): string {
return "匿名类";
}
};
echo $obj->hi(), "\n";
// intdiv
echo intdiv(10, 3), "\n";
// 引擎错误也能 catch 了(Throwable)
try {
intdiv(1, 0);
} catch (Throwable $e) {
echo get_class($e), "\n";
}Output
3
匿名
1 0 -1
red
匿名类
3
DivisionByZeroErrordeclare(strict_types=1) 让类型声明变成强制检查。不加的话,add("1", "2") 会被自动转成整数,静默通过。
PHP 7.4 的实用改进
PHP
<?php
// 类型化属性
class Point
{
public int $x = 0;
public ?string $label = null;
}
$p = new Point();
$p->x = 5;
echo $p->x, "\n";
// 箭头函数
$double = fn($n) => $n * 2;
echo $double(4), "\n";
// 数组展开
$a = [1, 2];
$b = [3, 4];
echo implode(",", [...$a, ...$b]), "\n";
// 空合并赋值
$cache = [];
$cache["k"] ??= "默认值";
echo $cache["k"], "\n";Output
5
8
1,2,3,4
默认值PHP 8 的关键特性
PHP
<?php
// 命名参数
function box(int $w, int $h): int {
return $w * $h;
}
echo box(h: 3, w: 4), "\n";
// match
echo match (2) {
1 => "一",
2 => "二",
default => "其它",
}, "\n";
// 构造器属性提升
class User
{
public function __construct(
public string $name,
public int $age = 0,
) {}
}
echo (new User("Tom", 18))->name, "\n";
// 空安全运算符
$maybe = null;
echo $maybe?->name ?? "无对象", "\n";
// 枚举
enum Level: int
{
case Low = 1;
case High = 2;
}
echo Level::High->name, "\n";Output
12
二
Tom
无对象
High?-> 在左边为 null 时短路整个链,不会报错。$a?->b()?->c 里任何一环是 null 都返回 null——比一层层 if ($a !== null) 清爽得多。升级建议
- 8.0 移除的 ——
each()、create_function()、真实类型检查更严 - 8.0 行为变更 —— 字符串与数字比较规则改了,
0 == "abc"现在是false - 8.1 弃用 —— 给未声明属性赋值(动态属性)
- 8.2 弃用 —— 动态属性全面弃用,
${var}字符串插值弃用 - 8.3 弃用 ——
get_class()无参调用等
升级前先跑
composer outdated 和静态分析(PHPStan / Psalm)。类型相关的破坏性变更占升级问题的大头,静态分析能在跑之前就抓出来。