$GLOBALS
访问限制现在对 $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),以前为 int(1)
var_dump(B::counter()); // int(4),以前为 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
现在,大多数非 final 内部方法都要求覆盖方法声明兼容的返回类型,否则在继承验证期间会发出弃用通知。如果由于 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 编码。