现在对 $GLOBALS 数组的访问受到一些限制。对 $GLOBALS['var']
这样的单个数组元素的读写访问继续按原样工作。对整个 $GLOBALS 数组的只读访问也继续受支持。但是,不再支持对整个 $GLOBALS 数组的写访问。例如,array_pop($GLOBALS)
将导致错误。
当使用静态变量的方法被继承(但未被覆盖)时,继承的方法现在将与父方法共享静态变量。
<?php
class A {
public static function counter() {
static $counter = 0;
$counter++;
return $counter;
}
}
class B extends A {}
var_dump(A::counter()); // int(1)
var_dump(A::counter()); // int(2)
var_dump(B::counter()); // int(3), previously int(1)
var_dump(B::counter()); // int(4), previously int(2)
?>
在必需参数之前指定的 可选参数 现在始终被视为必需参数,即使使用 命名参数 调用时也是如此。从 PHP 8.0.0 开始,但在 PHP 8.1.0 之前,以下代码在定义时会发出弃用通知,但在调用时会成功运行。从 PHP 8.1.0 开始,将抛出 ArgumentCountError 类的错误,就像使用位置参数调用时一样。
<?php
function makeyogurt($container = "bowl", $flavour)
{
return "Making a $container of $flavour yogurt.\n";
}
try
{
echo makeyogurt(flavour: "raspberry");
}
catch (Error $e)
{
echo get_class($e), ' - ', $e->getMessage(), "\n";
}
?>
上述示例在 PHP 8.0 中的输出
Deprecated: Required parameter $flavour follows optional parameter $container in example.php on line 3 Making a bowl of raspberry yogurt.
上述示例在 PHP 8.1 中的输出
Deprecated: Optional parameter $container declared before required parameter $flavour is implicitly treated as a required parameter in example.php on line 3 ArgumentCountError - makeyogurt(): Argument #1 ($container) not passed
现在,大多数非最终的内部方法都要求覆盖方法声明兼容的返回类型,否则在继承验证期间会发出弃用通知。如果由于 PHP 版本间兼容性问题而无法为覆盖方法声明返回类型,则可以添加 ReturnTypeWillChange 属性来消除弃用通知。
readonly
现在是关键字。但是,它仍然可以作为函数名使用。
never
现在是保留字,因此不能用于命名类、接口或特性,并且也禁止在命名空间中使用。
一些 资源 已迁移到 对象。使用 is_resource() 检查返回值应替换为检查 false
。
FTP 函数现在接受并返回 FTP\Connection 对象,而不是 ftp
资源。
IMAP 函数现在接受并返回 IMAP\Connection 对象,而不是 imap
资源。
LDAP 函数现在接受并返回 LDAP\Connection 对象,而不是 ldap link
资源。
LDAP 函数现在接受并返回 LDAP\Result 对象,而不是 ldap result
资源。
LDAP 函数现在接受并返回 LDAP\ResultEntry 对象,而不是 ldap result entry
资源。
PgSQL 函数现在接受并返回 PgSql\Connection 对象,而不是 pgsql link
资源。
PgSQL 函数现在接受并返回 PgSql\Result 对象,而不是 pgsql result
资源。
PSpell 函数现在接受并返回 PSpell\Dictionary 对象,而不是 pspell
资源。
PSpell 函数现在接受并返回 PSpell\Config 对象,而不是 pspell config
资源。
mysqli_fetch_fields() 和 mysqli_fetch_field_direct() 现在始终会为 max_length 返回 0
。此信息可以通过遍历结果集并获取最大长度来计算。这正是 PHP 之前在内部所做的。
MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH
选项不再有任何作用。
MYSQLI_STORE_RESULT_COPY_DATA
选项不再有任何作用。向 mysqli::store_result() 的 mode
参数传递任何值也不再有任何作用。
mysqli::connect() 现在在成功时返回 true
而不是 null
。
默认错误处理模式已从“静默”更改为“异常”。有关此更改的更多详细信息以及如何显式设置此属性,请参阅 MySQLi 报告模式 页面。要恢复之前的行为,请使用:mysqli_report(MYSQLI_REPORT_OFF);
扩展 mysqli_stmt::execute() 的类现在需要指定额外的可选参数。
mysqlnd.fetch_data_copy INI 指令已被移除。这不会导致用户可见的行为变化。
EC 私钥现在将以 PKCS#8 格式导出,而不是传统的格式,就像所有其他密钥一样。
openssl_pkcs7_encrypt() 和 openssl_cms_encrypt() 现在将默认使用 AES-128-CBC 而不是 RC2-40。RC2-40 密码被认为是不安全的,并且在 OpenSSL 3 中默认情况下未启用。
PDO::ATTR_STRINGIFY_FETCHES
现在将 bool 类型的数值转换为 "0"
或 "1"
。以前 bool 类型的值不会被转换为字符串。
使用 PDO::PARAM_LOB
调用 PDOStatement::bindColumn() 现在将始终绑定流结果,前提是未启用 PDO::ATTR_STRINGIFY_FETCHES
。以前,结果可能是流或字符串,具体取决于使用的数据库驱动程序和执行绑定的时间。
在使用模拟预处理语句时,结果集中的整数和浮点数现在将使用原生 PHP 类型而不是 string 类型返回。这与原生预处理语句的行为一致。可以通过启用 PDO::ATTR_STRINGIFY_FETCHES
选项来恢复以前的的行为。
结果集中的整数和浮点数现在将使用原生 PHP 类型返回。可以通过启用 PDO::ATTR_STRINGIFY_FETCHES
选项来恢复以前的的行为。
为了符合 ArrayAccess 接口,Phar::offsetUnset() 和 PharData::offsetUnset() 不再返回 bool 类型的值。
version_compare() 不再接受未记录的操作符缩写。
htmlspecialchars()、htmlentities()、htmlspecialchars_decode()、html_entity_decode() 和 get_html_translation_table() 现在默认使用 ENT_QUOTES | ENT_SUBSTITUTE
而不是 ENT_COMPAT
。这意味着 '
将被转义为 '
,而以前则不会进行任何操作。此外,格式错误的 UTF-8 将被替换为 Unicode 替换字符,而不是导致空字符串。
debug_zval_dump() 现在打印引用包装器的引用计数及其引用计数,而不是仅在值前面添加 &
。这更准确地模拟了 PHP 7.0 以后的引用表示。
debug_zval_dump() 现在打印 interned
而不是内部字符串和不可变数组的虚拟引用计数。
SplFixedArray 现在将像 array 一样进行 JSON 编码。