## 不向后兼容的变更

### PHP 核心

#### 调用栈非常接近溢出的程序

当程序接近溢出调用栈时，如果使用超过 zend.max_allowed_stack_size-zend.reserved_stack_size 字节的栈空间（对于纤程则是 fiber.stack_size-zend.reserved_stack_size）， 可能会抛出一个 Error。

#### 多次执行 proc_get_status()

在 POSIX 系统上多次执行 proc_get_status() 现在将始终返回正确的值。以前，函数只有在第一次调用时才会返回正确的值。proc_get_status() 之后执行 proc_close() 现在也会返回正确的退出码。之前会返回 `-1`。 在内部，这是通过缓存 POSIX 系统的结果实现的。如果需要之前的行为，可以检测 proc_get_status() 返回数组中的 `"cached"` 键，以检查结果是否已经缓存。

#### Zend Max Execution Timers

在 Linux 上，Zend Max Execution Timers 在 ZTS 编译中默认启用。

#### 使用带静态属性的 trait

使用带静态属性的 trait 现在会重新声明从父类继承的静态属性。这将为当前类创建单独的静态属性存储。这与不使用 trait 而将静态属性直接添加到当前类中类似。

#### 赋值负数索引到空数组

现在将负数索引 $n 赋值给空数组，将确保下一个索引为 `$n+1` 而不是 `0`。

#### 类常量可见性差别检查

从接口进行继承时，现在会正确的检查类常量的可见性差别。

#### 键映射到自身的 WeakMap 条目

如果该键只能通过迭代 WeakMap（认为通过迭代可达是弱可达性）才能访问到，那么在循环回收期间，现在可以删除键映射到自身（可能是传递）的 WeakMap 条目。

### Date

DateTime 扩展在 DateError 和 DateException 层次结构下引入了特定于 Date 扩展的 exception 和 error，而不是 warning 和通用 exception。这改善了错误处理，但需要检查 error 和 exception。

### DOM

现在对于没有父节点的节点调用 DOMChildNode::after()、DOMChildNode::before() 和 DOMChildNode::replaceWith() 时不会有任何操作，不会抛出层级结构异常，这是 DOM 规范要求的行为。

在没有文档的时候使用 DOMParentNode 和 DOMChildNode 方法可以正常工作，而不会抛出 `DOM_HIERARCHY_REQUEST_ERR` DOMException。这与 DOM 规范要求的行为一致。

不带指定前缀就调用 DOMDocument::createAttributeNS() 将错误的创建默认命名空间，并将元素放入到命名空间而不是元素中。这个错误现在已经修复。

当前缀已用于不同的 URI，DOMDocument::createAttributeNS() 之前会错误的抛出 `DOM_NAMESPACE_ERRNAMESPACE_ERR` DOMException。现在当前缀名称存在冲突时，将会正确的选择不同前缀。

为一些 DOM 类添加了新的方法和属性。如果用户空间类继承了这些类并声明了相同的属性和方法，则这些声明必须兼容。否则将会抛出典型的声明不兼容的编译错误。参阅新功能列表和新函数列表已获取新实现的方法和属性。

### FFI

当 C 函数有 void 返回类型时，现在返回 `null`，而不是返回对象 `object(FFI\CData:void) { }`

### Opcache

移除了 opcache.consistency_checks INI 指令。此功能与 tracing JIT 以及继承缓存不兼容，自 PHP 8.1.18 和 PHP 8.2.5 起，已禁用此功能，无法启用。脚本持久化后，因其检验和无效，导致 tracing JIT 以及继承缓存会修改 shm。尝试修复可跳过的可修改指针，但由于复杂性而被拒绝。因此决定移除此功能。

### Phar

Phar 类常量的类型现在已声明。

### 标准

range() 函数已经进行了各种更改：

- 当传递 object、resource 或 array 作为边界输入时，现在会抛出 TypeError。
- 当传递 `0` 作为 `$step` 时，现在会抛出更具描述性的 ValueError。
- 使用负数 `$step` 作为自增范围时现在会抛出 ValueError。
- 如果 `$step` 可以解释为整数的浮点数，那么现在就可以这样做。
- 如果任意参数是无穷大或者 NAN，现在会抛出 ValueError。
- 如果 `$start` 或 `$end` 是空字符串，现在会触发 `E_WARNING`。值将会转换为 `0`。
- 如果 `$start` 或 `$end` 超过 1 字节时，仅当其为非数字字符串时，现在会触发 `E_WARNING`。
- 如果 `$start` 或 `$end` 因为其它边界输入是数字（例如 `range(5, 'z');`）导致强制转换为整数，现在会触发 `E_WARNING`。
- 当尝试生成字符范围时，如果 `$step` 时浮点数，除非两个边界输入都是输字符串（例如 `range('5', '9', 0.5);` 不会产生警告），否则会触发 `E_WARNING`。
- 如果其中一个边界是数字字符串，另一个边界输入不转换为数字（例如 `range('9', 'A');`），现在 range() 会生成字符列表。

    <?php
    range('9', 'A');  // ["9", ":", ";", "<", "=", ">", "?", "@", "A"]，自 PHP 8.3.0 起
    range('9', 'A');  // [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]，PHP 8.3.0 之前
    ?>

number_format() 现在处理负的 `$decimals` 值，通过将 `$num` 四舍五入到小数点前的 `abs($decimals)` 位。以前，会忽略负的 `$decimals` 值。

file() flags 错误检查现在可以捕获所有无效的 flags。尤其是之前默默接受 `FILE_APPEND`。

### SNMP

SNMP 类常量的类型现在已声明。

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open