我有几个较旧的应用程序,当在E_NOTICE错误级别上运行时,它们会抛出许多"xyz is undefined“和"undefined offset”消息,因为不会使用isset()和consorts显式检查变量的存在。
我正在考虑通过它们来使它们与E_NOTICE兼容,因为关于丢失变量或偏移量的通知可以是救命稻草,可能会有一些小的性能改进,而且总体上是更干净的方式。
然而,我不喜欢成百上千的isset() empty()和array_key_exists()对我的代码造成的影响。它变得臃肿,可读性变差,没有任何价值或意义。
如何在不进行过多变量检查的情况下构建代码结构,同时又与E_NOTICE兼容?
发布于 2009-12-25 13:57:11
对于感兴趣的人,我已经将这个主题扩展为一篇小文章,它以一种更好的结构化形式提供了以下信息:The Definitive Guide To PHP's isset And empty
我想你应该考虑的不仅仅是让这个应用程序"E_NOTICE兼容“,而是整个事情的重组。在你的代码中有数百个点经常尝试使用不存在的变量,这听起来像是一个结构相当糟糕的程序。尝试访问不存在的变量永远不应该发生,其他语言在编译时会对此犹豫不决。PHP允许这样做并不意味着您应该这样做。
这些警告是为了帮助你,而不是为了惹恼你。如果您收到警告“您正在尝试使用不存在的东西!”,您的反应应该是“哦,我的错,让我尽快修复它。”否则你将如何区分“工作正常的变量未定义”和可能导致严重错误的错误代码??这也是为什么你总是,总是使用错误报告turned to 11进行开发,并且一直在你的代码上努力,直到一个NOTICE都没有发出。关闭错误报告仅适用于生产环境,以避免信息泄漏并提供更好的用户体验,即使面对错误代码也是如此。
详述:
您总是需要在代码中的某个位置使用isset或empty,减少它们出现的唯一方法是正确地初始化您的变量。根据情况,有不同的方法可以做到这一点:
函数参数:
function foo ($bar, $baz = null) { ... }不需要检查是否在函数内部设置了$bar或$baz,因为您只需设置它们,您只需担心它们的值是否为true或false (或其他任何值)。
任何地方的常规变量:
$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以外的任何含义,例如,如果在上面的示例中,isset和array_key_exists的不同结果对您的程序逻辑造成了不同,那么您应该问问自己为什么。一个变量的存在并不重要,只有它的值才是重要的。如果键是true/false标志,则使用true或false,而不是null。唯一的例外是希望null有意义的第三方库,但由于null在PHP中很难检测,我还没有找到任何这样做的库。
发布于 2009-12-25 13:30:48
只需为此编写一个函数即可。类似于:
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()等琐碎的东西做同样的事情。
发布于 2009-12-25 21:40:58
我认为解决这个问题的最好方法之一是访问GET和POST的值(COOKIE、SESSION等)。通过一个类创建数组。
为每个数组创建一个类,并声明__get和__set方法(overloading)。__get接受一个参数,它将是一个值的名称。此方法应使用isset()或empty()在相应的全局数组中检查该值,如果该值存在,则返回该值,否则返回null (或其他一些默认值)。
之后,您可以放心地以这种方式访问数组值:$POST->username,并在需要时执行任何验证,而无需使用任何isset()或empty()。如果相应的全局数组中不存在username,则将返回null,因此不会生成任何警告或通知。
https://stackoverflow.com/questions/1960509
复制相似问题