属性挂钩 (Property Hooks)
传统方式需要为 fullName这类计算属性编写独立的 getter 和 setter 方法。现在,逻辑可以直接内嵌在属性定义中。
// PHP 8.4 之前
class UserOld {
public function __construct(private string $firstname, private string $lastname) {}
public function getFullname(): string {
return $this->firstname . ' ' . $this->lastname;
}
public function setFullname(string $fullname): void {
[$this->firstname, $this->lastname] = explode(' ', $fullname, 2);
}
}
// PHP 8.4 使用属性挂钩
class User {
public function __construct(private string $firstname, private string $lastname) {}
public string $fullname {
get => $this->firstname . ' ' . $this->lastname;
set => [$this->firstname, $this->lastname] = explode(' ', $value, 2);
}
}
不对称可见性
现在可以独立地控制写入属性的作用域和读取属性的作用域,减少了需要编写繁琐的 getter 方法来公开属性值而不允许从类外部修改属性的需求。
// PHP 8.4 之前
class PhpVersion
{
private string $version = '8.3';
public function getVersion(): string
{
return $this->version;
}
public function increment(): void
{
[$major, $minor] = explode('.', $this->version);
$minor++;
$this->version = "{$major}.{$minor}";
}
}
// PHP 8.4
class PhpVersion
{
public private(set) string $version = '8.4';
public function increment(): void
{
[$major, $minor] = explode('.', $this->version);
$minor++;
$this->version = "{$major}.{$minor}";
}
}
// PHP 8.4
class Book
{
public function __construct(
public private(set) string $title,
public protected(set) string $author,
protected private(set) int $pubYear,
) {}
}
class SpecialBook extends Book
{
public function update(string $author, int $year): void
{
$this->author = $author; // OK
$this->pubYear = $year; // Fatal Error
}
}
$b = new Book('How to PHP', 'Peter H. Peterson', 2024);
echo $b->title; // Works
echo $b->author; // Works
echo $b->pubYear; // Fatal Error
$b->title = 'How not to PHP'; // Fatal Error
$b->author = 'Pedro H. Peterson'; // Fatal Error
$b->pubYear = 2023; // Fatal Error
新的数组函数
新的数组函数让查找和验证操作变得非常简洁。
$numbers = [1, 3, 5, 8, 9];
// 查找第一个偶数
$firstEven = array_find($numbers, fn($n) => $n % 2 === 0); // 结果为 8
// 查找返回满足回调函数的第一个元素的键
$array = [
'a' => 'dog',
'b' => 'cat',
'c' => 'cow',
'd' => 'duck',
'e' => 'goose',
'f' => 'elephant'
];
var_dump(array_find_key($array, function (string $value) {
return strlen($value) > 4; // 结果为 e
}));
// 检查数组中是否有任何大于 10 的数字
$hasBigNumber = array_any($numbers, fn($n) => $n > 10); // 结果为 false
// 检查是否所有数字都是正数
$allPositive = array_all($numbers, fn($n) => $n > 0); // 结果为 true
BCMath 的对象 API
新的 BcMath\Number 对象使在处理任意精度数字时可以使用面向对象的方式和标准的数学运算符。
// PHP 8.4 之前
$num1 = '0.12345';
$num2 = '2';
$result = bcadd($num1, $num2, 5);
echo $result; // '2.12345'
var_dump(bccomp($num1, $num2) > 0); // false
// PHP 8.4
use BcMath\Number;
$num1 = new Number('0.12345');
$num2 = new Number('2');
$result = $num1 + $num2;
echo $result; // '2.12345'
var_dump($num1 > $num2); // false
new MyClass()->method() 不需要括号
现在可以在不使用括号包裹 new 表达式的情况下访问新实例化对象的属性和方法。
// PHP 8.4 之前
class PhpVersion
{
public function getVersion(): string
{
return 'PHP 8.3';
}
}
var_dump((new PhpVersion())->getVersion());
// PHP 8.4
class PhpVersion
{
public function getVersion(): string
{
return 'PHP 8.4';
}
}
var_dump(new PhpVersion()->getVersion());
pcntl函数族扩充
| 函数名 | 作用描述 | 返回值类型 | 适用平台 |
|---|---|---|---|
| pcntl_getcpu() | 获取当前进程正在运行的 CPU 编号。 | int | 广泛支持 (Linux 常见) |
| pcntl_getcpuaffinity() | 获取进程的 CPU 亲和性掩码,即进程被允许在哪些 CPU 核心上运行。 | array 或 false | Linux |
| pcntl_getqos_class() | 获取进程的 服务质量(QoS)类别,反映其调度优先级。 | int 或 false | macOS |
| pcntl_setns() | 将当前进程加入指定的 内核命名空间(如网络、挂载点命名空间)。 | bool | Linux |
| pcntl_waitid() | 一个功能更强大的等待子进程状态变化的函数,提供比 pcntl_wait()更精确的控制。 | bool | 类 Unix 系统 |