何时抑制PHP中的错误

何时抑制PHP中的错误,php,error-handling,Php,Error Handling,我有一些变量可能是定义的,也可能不是定义的(一个$isLoggedIn布尔值),我正在尝试清除错误消息。我想知道是否有任何理由我不应该使用错误抑制器操作符: if (@$isLoggedIn) 或者如果我应该先检查变量的存在性: if (isset($isLoggedIn)and$isLoggedIn) 在生产环境中,这两种方法是否有任何缺点/好处?这两条语句的功能是相同的,并且不存在由于未定义此变量而导致的问题。但不应将其记录为错误。如果使用的是变量,则该变量应存在。您的代码不应该抑制错误

我有一些变量可能是定义的,也可能不是定义的(一个
$isLoggedIn
布尔值),我正在尝试清除错误消息。我想知道是否有任何理由我不应该使用错误抑制器操作符:

if (@$isLoggedIn)
或者如果我应该先检查变量的存在性:

if (isset($isLoggedIn)and$isLoggedIn)

在生产环境中,这两种方法是否有任何缺点/好处?这两条语句的功能是相同的,并且不存在由于未定义此变量而导致的问题。但不应将其记录为错误。

如果使用的是变量,则该变量应存在。您的代码不应该抑制错误,您应该修复或处理错误。

根据我的经验,您永远不应该抑制单个级别的错误。在生产环境中,将错误报告设置为0,将显示错误设置为关闭。当你在6个月内回来修复一个错误时,拥有这样的个人优势就等于是在打你自己的脚,忘记了错误就在那里,也不知道为什么没有错误出现,但某些东西显然被打破了


在特定情况下,只需将$isLoggedIn设置为false,然后在当前实例化它的位置覆盖该值(我在这里假设代码结构)。

最符合逻辑的方法是始终声明这些变量,特别是像
$isLoggedIn
这样的重要变量,并检查其是否为true:

if ($isLoggedIn)
 if (isset($isLoggedIn)
或仅设置为真:

if ($isLoggedIn)
 if (isset($isLoggedIn)

在我看来,第一种选择更好,两者混合不是一个好的解决方案

在代码中有一堆错误抑制器会使维护变得更加困难,尤其是对于您以外的人。下一个人现在必须学会以他习惯的不同方式看待代码。抑制只是一种黑客行为,会导致其他人试图找出为什么会有一种黑客行为会减慢任何调试工作

执行if(@$var)会产生与if(!empty($var))相同的结果,因此只需使用它,因为这是一种语义上更正确的检查方法。

您的变量应该始终存在,至少将其初始化为false,登录后将其设置为true。在抑制方面,我建议使用第二种方法

警告


当前,错误控制运算符前缀“@”甚至会禁用将终止脚本执行的关键错误的错误报告。除其他外,这意味着如果使用“@”来抑制某个函数的错误,并且该函数不可用或输入错误,脚本将立即停止运行,并且没有说明原因。

如果我不确定是否设置了变量,但我想知道它是否为真,那么我写:

if(!empty($var)){}
但是,您仍然应该构造代码,以便始终确定变量。
您应该避免使用全局变量。

我认为,最好的选择不是使用PHP的基本警告系统,而是尽可能使用可用的异常处理。将警告也转换为异常,以便以相同的方式处理所有问题

您可以捕获特定的错误。未被特定处理程序捕获的全局错误可以也应该被常规处理程序捕获。这样,您就可以捕获所有这些错误,并在日志中报告它们和/或将它们发送给开发部门(或您自己)

对于用户来说,您不应该在生产环境中显示这些错误,特别是当它们包含SQL错误或关于缺少变量的消息时。通过显示一些通用内容和一条通用的、用户友好的错误消息(如果必须的话),让页面优雅地消失,但要隐藏技术内容


但绝对不要忽略或隐藏异常,因为这将使调试成为一个地狱。

您永远不应该允许PHP在公共网站上向浏览器写入错误消息。您应该始终记录它们,并且尽可能在代码中处理它们-即使是通过set_error_handler()的方式

现在我们已经解决了这个问题

这是一个警告,不是错误

是的,警告信息有时可能是PITA。但是有些人喜欢严格的变量检查。使用suppression操作符提供了一种比抑制所有E_STRICT消息更具针对性的方法,因此,尽管我喜欢PHP对允许使用不带声明的变量的支持,但这就是我要做的(在适当的地方也使用try{}catch()


因此,在适当的情况下使用任何一种方法-但在警告未被抑制时,请记录这些警告-这些是您需要修复的事情-即使修复只是添加抑制。

+1询问。希望其他人能从我看到的答案中学习,我得到了a-1。我不知道为什么,因为这是一个很好的建议。@goleztroll我想有人对我投了反对票,因为我今天发布了很长很长的答案。谢谢,我不知道@是否也会抑制关键错误。我只需要设置变量…这不是我的代码,所以我不想深入研究并纠正这样一个小问题,但我想这是重构的一部分。当然,我不会让它在生产中输出错误,但我想要一份产品站点的相关错误日志。正如其他人所建议的那样,我只是要实例化这个变量。