PHP中的“Notice: Undefined index”是无害的还是真正的错误?

4

当我的网站一直正常运行时,突然间服务器的CPU使用率变得非常高,于是我开始仔细检查代码,并启用了E_ALL错误报告。

接着我发现我有很多这样的"通知(notices)":

Notice: Undefined index: userID in /var/www/vhosts/mydomain.com/httpdocs/header.php on line 8

大多数情况下,它们指的是取消设置的 cookies,例如以下内容:

$uid = $_COOKIE['userID'];

如果用户未登录,我会在那里收到通知,并且每次使用“$uid”。我想知道的是:这些通知是否无害,还是会对我的网站造成任何问题?(速度问题、错误等)

你能展示一下你的 setcookie 吗? - Nikola K.
在大多数情况下,它们并不危险,但处理它们是一个好的实践。 - 1321941
这并不是“危险”的 :) 但它确实很重要。错误会减慢 PHP 的速度。 - Nikola K.
1
我的个人偏好是将每一个 E_NOTICE 都视为错误,并确保应用程序永远不会生成它,即使它是“无害”的。 - Matthew
@Nikola K. 这是我的setcookie代码:setcookie($name,$value,time() + 2*7*24*60*60,'/','lujanventas.com', false)老实说,我不知道'false'的含义,但我很久以前就复制粘贴了它,然后就一直沿用至今。 - lisovaccaro
4个回答

10
这只是一条通知,请尝试使用以下代码:
$uid = isset($_COOKIE['userID']) ? $_COOKIE['userID'] : 0;

这并不是无害的(根据观点而定),您可以使用错误报告功能禁用它,否则正确的方法是验证索引是否存在isset($_COOKIE['userID']),如果不存在,则定义一个默认值(例如null

$var = isset($foo) ? $foo : 'default';

如果您不确定变量是否存在,需要进行验证。

$var = 'foo'
if($var == 'foo') { // I known $var is defined, because I have defined it.
    [..]
}

/** 
 * Above, I don't known if user go to mywebsite.com/index.php or
 * mywebsite.com/index.php?foo=bar, so, I need to verify if index is defined
 */
if(isset($_GET['foo']) && $_GET['foo'] == 'bar') {
    [...]
}

1
或者是-1,如果ID从0开始的话 ;) - nico
1
@Gabriel Santos:没有,但我以前见过。尤其是那个人把管理员赋值为0...你可以想象那会带来什么灾难 :) - nico
1
@Liso 简单来说:如果你试图使用不存在的值/变量,你的应用程序就会进入未知状态。你想使用 $_COOKIE['userId'] 的值,并期望它是一个数字字符串。但是这个值并不存在。现在怎么办?这可能会导致后续错误,也可能不会。你需要预期并明确处理“值可能不存在”的情况,以确保你的应用程序在这种情况下的行为是100%确定的。 - deceze
1
@Liso22 如果你在 $var 不存在的情况下执行 if(!$var),你将会得到错误。你需要这样做:if(isset($var) && !$var),它会验证 $var 是否被定义且为 false - Gabriel Santos
1
一个很有用的简写形式用于isset()和两个选项,即双问号:$var = $foo ?? : 'default'。自从PHP 7.0可用。 - David Šili
显示剩余4条评论

2
那些通知会导致一点点速度问题,因为发出一个通知需要额外的努力。
然而,主要问题在于这是一个严重错误。您试图使用不存在的东西。这可能会导致糟糕的事情发生,也可能不会,但这意味着您的程序不正确。由于应始终开启错误报告以查看和解决实际问题,有关未定义索引或未定义变量的通知是严重的,并且需要解决。任何PHP抱怨的事情都是严重的,并且需要解决。请参见PHP's isset And empty的权威指南

1

通知一般是无害的,但它们可能表明应用程序设计不佳。通常最好利用可用的PHP工具(例如isset($someVar))确保您的业务逻辑正确处理变量初始化。当您使用E_ALL错误报告设置时没有看到此类通知时,总是更好的。


0

注意警告在第一人称看来是无害的,但你应该记住,编程不正确可能会导致后续代码出现错误。

在你的例子中最好使用

$uid = isset($_COOKIE['userID'])?$_COOKIE['userID']:0;

所以你可以确定,$uid总是有一个值的,当这个值大于0时,你就拥有了一个有效的用户ID...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接