一尘不染

如何避免isset()和empty()

php

我有几个较旧的应用程序,它们在E_NOTICE错误级别上运行时会抛出很多“
xyz未定义”和“未定义偏移”消息,因为没有使用isset()和明确检查变量的存在。

我正在考虑通过它们使它们与E_NOTICE兼容,因为有关丢失变量或偏移量的通知可能会节省生命,可能会获得一些较小的性能改进,并且总体而言,这是一种更清洁的方法。

但是,我不喜欢什么造成数百isset() empty()array_key_exists()S
^确实给我的代码。它变得肿,可读性降低,而没有获得任何价值或意义。

如何在不进行过多变量检查的情况下构造代码,同时又能与E_NOTICE兼容?


阅读 304

收藏
2020-05-26

共1个答案

一尘不染

恕我直言,您不仅应该考虑使应用程序“与E_NOTICE兼容”,还应该对整个事情进行重组。在您的代码中有 数百个
点经常尝试使用不存在的变量听起来像一个结构很差的程序。尝试访问不存在的变量永远不会发生,其他语言在编译时会对此表示沮丧。PHP允许您这样做的事实并不意味着您应该这样做。

这些警告可以 帮助 您,而不会惹恼您。如果收到警告 “您正在尝试使用不存在的东西!” ,您的反应应该是 “糟糕,我的糟糕,让我尽快解决该问题。”
您还如何区分 “在未定义的范围内有效的变量”可能导致严重错误的诚实错误代码 之间的区别?这也是为什么您始终 _总是_将错误报告转为11并继续插入代码直到没有一个出现的原因NOTICE发行。关闭错误报告仅适用于生产环境,从而避免信息泄漏并即使面对错误代码也能提供更好的用户体验。


详细说明:

您将始终需要在代码中issetempty代码中的某个位置,减少它们出现的唯一方法是正确初始化变量。根据情况,有不同的方法可以执行此操作:

函数参数:

function foo ($bar, $baz = null) { ... }

有没有必要检查是否$bar$baz设置里面的功能,因为你设置它们,你需要担心的是,如果他们的价值评估为truefalse(或任何其他)。

任何地方的常规变量:

$foo = null;
$bar = $baz = 'default value';

在将要使用它们的代码块的顶部初始化变量。这样可以解决!isset问题,确保您的变量始终具有已知的默认值,使读者可以了解以下代码将要处理的内容,从而也可以作为一种自说明文件。

数组:

$defaults = array('foo' => false, 'bar' => true, 'baz' => 'default value');
$values = array_merge($defaults, $incoming_array);

与上述相同,您正在使用默认值初始化数组,并使用实际值覆盖它们。

在其余情况下,假设您要在模板中输出可能由控制器设置或可能未设置的值,则只需检查以下内容:

<table>
    <?php if (!empty($foo) && is_array($foo)) : ?>
        <?php foreach ($foo as $bar) : ?>
            <tr>...</tr>
        <?php endforeach; ?>
    <?php else : ?>
        <tr><td>No Foo!</td></tr>
    <?php endif; ?>
</table>

如果您发现自己经常使用array_key_exists,则应该评估其用途。唯一的改变是在这里:

$array = array('key' => null);
isset($array['key']); // false
array_key_exists('key', $array); // true

如上所述,但是,如果您正确初始化变量,则无需检查键是否存在,因为您知道它确实存在。如果您收到来自外部源的阵列,该值将最有可能不是null,但是''0'0'false或类似的东西,也就是一个值,你可以用评估isset或者empty,这取决于你的意图。如果您定期将数组键设置为,null并希望它的含义不是false,即在上例中,如果程序逻辑的不同结果issetarray_key_exists不同之处,您应该问自己为什么。仅仅存在一个变量并不重要,只有其值才有意义。如果键是true/
false标志,则使用true或者false,不是null。唯一的例外是希望null表示某些含义的第三方库,但是由于null很难在PHP中检测到,因此我尚未找到任何可以做到这一点的库。

2020-05-26