如何避免 isset() 和 empty()

2022-08-30 07:39:49

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

我正在考虑通过它们使它们E_NOTICE兼容,因为有关缺少变量或偏移的通知可以挽救生命,可能会获得一些小的性能改进,并且总体上是更干净的方式。

但是,我不喜欢施加数百个和s对我的代码的影响。它变得臃肿,变得不那么可读,在价值或意义方面没有任何收获。isset()empty()array_key_exists()

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


答案 1

对于那些感兴趣的人,我已经将这个主题扩展为一篇小文章,它以更好的结构化形式提供了以下信息:PHP的权威指南和空


恕我直言,您不仅应该考虑使应用程序“E_NOTICE兼容”,而且应该重组整个事情。在你的代码中有数百个点经常尝试使用不存在的变量,这听起来像是一个相当糟糕的结构程序。尝试访问不存在的变量应该永远不会发生,其他语言在编译时对此犹豫不决。PHP允许你这样做的事实并不意味着你应该这样做。

这些警告是为了帮助你,而不是惹恼你。如果你收到一条警告“你正在尝试使用不存在的东西!”,你的反应应该是“哎呀,我的坏,让我尽快解决这个问题。否则,您将如何区分“未定义正常工作的变量”可能导致严重错误的诚实错误代码?这也是为什么你总是,总是,在错误报告变成11的情况下进行开发,并继续插入你的代码,直到没有发出任何代码。关闭错误报告仅适用于生产环境,以避免信息泄露,即使在面对有缺陷的代码时也能提供更好的用户体验。NOTICE


详细说明:

您将始终需要或在代码中的某个位置,减少其发生的唯一方法是正确初始化变量。根据具体情况,有不同的方法可以做到这一点:issetempty

函数参数:

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

无需检查函数内部是否设置了 或,因为您只需设置它们,所有您需要担心的是它们的值是否计算为 或(或其他任何值)。$bar$baztruefalse

任意位置的常规变量:

$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

如上所述,如果您正确初始化变量,则无需检查密钥是否存在,因为您知道它确实如此。如果您从外部源获取数组,则该值很可能不是 but 、 、 或类似的东西,即,您可以根据自己的意图使用 或 进行计算的值。如果你经常设置一个数组键,并希望它意味着除 ,即如果在上面的例子中,不同的结果对你的程序逻辑产生影响,你应该问问自己为什么。变量的存在本身并不重要,只有它的值才应该具有后果。如果键是 / 标志,则使用 或 ,而不是 。唯一的例外是想要表达某种含义的第三方库,但由于在PHP中很难检测到,我还没有找到任何这样做的库。null''0'0'falseissetemptynullfalseissetarray_key_existstruefalsetruefalsenullnullnull


答案 2

只需为此编写一个函数即可。像这样:

function get_string($array, $index, $default = null) {
    if (isset($array[$index]) && strlen($value = trim($array[$index])) > 0) {
        return get_magic_quotes_gpc() ? stripslashes($value) : $value;
    } else {
        return $default;
    }
}

您可以将其用作

$username = get_string($_POST, 'username');

对琐碎的东西做同样的事情,如 、 等。get_number()get_boolean()get_array()


推荐