处理 PHP 8.1 未定义数组键的警告

Jef*_*mon 8 php associative-array undefined php-8.1

我们正在升级到 PHP 8.1。一个新功能是未定义的数组键会引发警告。

不幸的是,这会妨碍轻松使用关联数组(例如 $_SESSION 变量)的能力。我了解预定义变量的优点,并且不寻求对这些优点进行讨论。关联数组的想法是,您可以轻松地将内容添加到会话中,并且所有未分配的内容都会被评估为 null。但现在它也发出了警告;必须采取一些措施来解决这个问题。

这是一些代码的示例:

$_SESSION['is_condition'] = true;
Run Code Online (Sandbox Code Playgroud)

在代码的另一个地方,出现以下情况

if ($_SESSION['is_condition']) ...
Run Code Online (Sandbox Code Playgroud)

如果这种情况发生在“is_condition”会话变量尚未定义的上下文中,则将其值评估为 null 的期望结果就是我们想要的。但现在必须采取其他措施来处理它未定义的可能性。

有几种方法可以处理这个问题:

  1. 预定义所有值为 null 的会话变量。看起来这不是关联数组的精神。现在每个脚本都必须调用一组冗长的代码。

  2. 每当需要关联数组元素的值时,请使用空合并运算符。在整个代码库中放置很多很多额外的运算符是一个丑陋的要求。

  3. 更改我们的自定义错误处理函数以忽略未定义的数组键错误。抑制警告是一个非常糟糕的主意,并且会增加开销。

这些方法都不是非常理想的。

解决这个问题的理论上的方法是使用数组初始化语句,将所有可能的关联键分配为 null。我不知道有这样的事情。

我的问题是是否还缺少其他一些方法,例如仅抑制此特定警告的参数。

jhm*_*imm 5

我的建议是在会话机制上编写一个抽象来处理这个问题。我会选择一个类,但即使是一个简单的函数也可以工作:

function getValueFromSession(string $key, mixed $defaultValue = null) : mixed
{
   return isset($_SESSION[$key]) ? $_SESSION[$key] : $defaultValue;
}
Run Code Online (Sandbox Code Playgroud)

这样做的另一个好处是允许您更改底层会话存储(例如更改为 Redis),而无需更改会话值访问的每个实例。


Nic*_*ski 1

您假设它$_SESSION['whatever']始终可用。您可以使用 isset 包装所有条件,如下所示:

if (isset($_SESSION['is_condition'])) {
//Do Whatever
}
Run Code Online (Sandbox Code Playgroud)

或者您可以做一些不方便的事情,例如将其放在文件的顶部。

if (isset($_SESSION['is_condition'])) {
//Do something
} else {
$_SESSION['is_condition'] = NULL;
} 
Run Code Online (Sandbox Code Playgroud)

从那时起,每当您检查该密钥的会话时,它至少都会被设置为某些内容,并且不会引发警告或通知。它很丑陋,但它会起作用。