Pek*_*ica 96 php error-reporting
我有几个较旧的应用程序,当在E_NOTICE错误级别上运行时会抛出大量"xyz未定义"和"未定义的偏移"消息,因为没有使用isset()和consorts 显式检查变量的存在.
我正在考虑通过它们来使它们与E_NOTICE兼容,因为关于缺失变量或偏移的通知可以是救生员,可能会获得一些微小的性能改进,并且它总体上更清洁.
但是,我不喜欢对我的代码造成数百isset() empty()和array_key_exists()s的影响.它变得臃肿,变得不那么可读,没有在价值或意义上获得任何东西.
如何在没有过多变量检查的情况下构建代码,同时还兼容E_NOTICE?
dec*_*eze 127
对于那些感兴趣的人,我已经将这个主题扩展为一篇小文章,它以更好的结构化形式提供了以下信息:PHP的权威指南isset和空
恕我直言,你应该考虑不只是使应用程序"E_NOTICE兼容",而是重组整个事情.在代码中有数百个点经常尝试使用不存在的变量听起来像一个结构相当糟糕的程序.尝试访问不存在的变量永远不应该发生,其他语言在编译时就不会这样做了.PHP允许你这样做的事实并不意味着你应该这样做.
这些警告可以帮助你,而不是惹恼你.如果你收到警告"你正在尝试使用不存在的东西!" ,你的反应应该是"哎呀,我的坏,让我尽快解决." 你怎么能分辨出"工作得很好的变量"和真正错误的代码之间的区别可能会导致严重错误?这也是您始终始终将错误报告转换为11并继续插入代码直到没有NOTICE发布单一内容的原因.关闭错误报告仅适用于生产环境,以避免信息泄漏并提供更好的用户体验,即使面对错误的代码.
详细说明:
您将始终需要isset或empty在代码中的某个位置,减少其发生的唯一方法是正确初始化变量.根据具体情况,有不同的方法:
函数参数:
function foo ($bar, $baz = null) { ... }
Run Code Online (Sandbox Code Playgroud)
有没有必要检查是否$bar或$baz设置里面的功能,因为你设置它们,你需要担心的是,如果他们的价值评估为true或false(或任何其他).
任何地方常规变量
$foo = null;
$bar = $baz = 'default value';
Run Code Online (Sandbox Code Playgroud)
在您要使用它们的代码块的顶部初始化变量.这解决了这个!isset问题,确保您的变量始终具有已知的默认值,让读者了解以下代码的工作原理,从而也可以作为一种自我文档.
阵列:
$defaults = array('foo' => false, 'bar' => true, 'baz' => 'default value');
$values = array_merge($defaults, $incoming_array);
Run Code Online (Sandbox Code Playgroud)
与上面相同,您使用默认值初始化数组并使用实际值覆盖它们.
在其余的情况下,假设您输出可能由控制器设置或未设置的值的模板,您只需要检查:
<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>
Run Code Online (Sandbox Code Playgroud)
如果您发现自己经常使用array_key_exists,则应评估您正在使用它的内容.它唯一有意义的是:
$array = array('key' => null);
isset($array['key']); // false
array_key_exists('key', $array); // true
Run Code Online (Sandbox Code Playgroud)
如上所述,如果您正确初始化变量,则无需检查密钥是否存在,因为您知道密钥是否存在.如果您收到来自外部源的阵列,该值将最有可能不是null,但是'',0,'0',false或类似的东西,即价值,你可以用评估isset或者empty,这取决于你的意图.如果你经常设置一个数组键,null并希望它具有任何意义,但是false,如果在上面的例子中,你的程序逻辑的不同结果isset和array_key_exists差异,你应该问问自己为什么.变量的存在不应该是重要的,只有它的价值应该是重要的.如果密钥是true/ falseflag,则使用true或false不使用null.唯一的例外是想要null表达某些东西的第三方库,但由于null在PHP中很难检测到,我还没有找到任何这样做的库.
Bal*_*usC 37
只需为此编写一个函数.就像是:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
你可以用作
$username = get_string($_POST, 'username');
Run Code Online (Sandbox Code Playgroud)
做同样的琐碎的东西一样get_number(),get_boolean(),get_array()等等.
Jam*_*mol 13
我相信解决这个问题的最佳方法之一是通过类访问GET和POST(COOKIE,SESSION等)数组的值.
为每个数组创建一个类,声明__get和__set方法(重载).__get接受一个参数,它将是一个值的名称.此方法应使用isset()或检查相应全局数组中的此值,empty()如果存在,则返回该值,否则返回null(或某些其他默认值).
之后,您可以以这种方式自信地访问数组值:$POST->username如果需要,可以在不使用任何isset()s或empty()s的情况下进行任何验证.如果username在相应的全局数组中不存在null则将返回,因此不会生成警告或通知.
我不介意使用array_key_exists(),其实我更喜欢使用这个特定的功能,而不是依靠黑客可能会改变他们的行为在未来的功能像(strikedthrough避免敏感性).empty和isset
但是,我会使用一个简单的函数来处理数组索引,以及其他一些处理数组索引的情况:
function Value($array, $key, $default = false)
{
if (is_array($array) === true)
{
settype($key, 'array');
foreach ($key as $value)
{
if (array_key_exists($value, $array) === false)
{
return $default;
}
$array = $array[$value];
}
return $array;
}
return $default;
}
Run Code Online (Sandbox Code Playgroud)
假设你有以下数组:
$arr1 = array
(
'xyz' => 'value'
);
$arr2 = array
(
'x' => array
(
'y' => array
(
'z' => 'value',
),
),
);
Run Code Online (Sandbox Code Playgroud)
你如何从阵列中获得"价值"?简单:
Value($arr1, 'xyz', 'returns this if the index does not exist');
Value($arr2, array('x', 'y', 'z'), 'returns this if the index does not exist');
Run Code Online (Sandbox Code Playgroud)
我们已经覆盖了大学和多维数组,我们还能做些什么呢?
以下面的代码为例:
$url = 'https://stackoverflow.com/questions/1960509';
$domain = parse_url($url);
if (is_array($domain) === true)
{
if (array_key_exists('host', $domain) === true)
{
$domain = $domain['host'];
}
else
{
$domain = 'N/A';
}
}
else
{
$domain = 'N/A';
}
Run Code Online (Sandbox Code Playgroud)
很无聊不是吗?这是另一种使用该Value()功能的方法:
$url = 'https://stackoverflow.com/questions/1960509';
$domain = Value(parse_url($url), 'host', 'N/A');
Run Code Online (Sandbox Code Playgroud)
$ip = Value($_SERVER, 'HTTP_CLIENT_IP', Value($_SERVER, 'HTTP_X_FORWARDED_FOR', Value($_SERVER, 'REMOTE_ADDR')));
Run Code Online (Sandbox Code Playgroud)