E_NOTICE:真的有必要修复每一个吗?

时间:2012-07-16 18:29:43

标签: php error-handling

首先我知道这个问题不止一次出现在这里:

但是我修复所有E_NOTICE(就像人们说你应该的那样)越多,我就越注意到:

  • 我是微优化
  • 我实际上正在制作更多代码并使我的代码更难以保持和更慢

举个例子:

假设你使用MongoDB PHP驱动程序,并且在一个类中MongoDate的类ts中有一个$obj->ts->sec对象,该类表示数据库中集合中的单个行。现在你访问这个var就像:ts但是PHP抛出一个拟合(E_NOTICE),因为在这种情况下ts本身没有定义为一个对象,因为这个特定的行没有date()领域。所以你认为这是好的,这是期望的行为,如果它没有设置返回null并且我将在解释器自己的机器人工作之外自己处理它(因为你将它包装在刚刚返回的1970函数中{ {1}}如果var为nullnone-object)。

但是现在要修复E_NOTICE作为另一个开发人员真的想要我,因为任何E_NOTICE都是terribad并且它使得代码变慢而不能根据错误执行。所以我在名为$obj的{​​{1}}类中创建了一个新函数,我给它3行,实际上除了检查getTs var是否是ts对象之外什么都不做如果它是......那就归还它。

为什么? PHP不能在其快速的解释器中为我做这件事,而不是在应用程序本身的运行时间内完成它吗?我的意思是每一个我必须为我的代码添加无用的凸点,几乎是空的函数来检测我实际上刚刚处理的变量,我们有能力返回MongoDate或在我真正需要时检查他们的null to(当它对所述函数的操作和行为至关重要时)并且不让我开始instanceof s我已经添加了大约300行isset() s,它已经失去控制。我当然要制作这个isset()函数,因为你不能这样做:

getTs

我要么必须将class obj{ public $ts = new MongoDate(); } 存储在ts中(我对它也不太满意,我使用了很多魔法)或使用函数来检测是否它是设定的(我现在这样做)。

我的意思是我明白为什么要修理:

  • 未定义的变种
  • 指定未设置的变量(__constructor变量)
  • 的属性
  • 常数错误等

但是,如果您已经测试了代码,并且您知道它是安全的,并且只会以您希望的方式工作,那么修复所有nullundefined index错误的重点是什么?是不是在代码中添加了一堆none-object和2行函数实际上是微优化?

我注意到,在使我的网站符合E_NOTICE标准的一半之后,实际上它现在使用了更多的CPU,内存和时间......所以真正处理每个E_NOTICE错误的重点是什么,而不仅仅是ARE错误?

感谢您的想法,

2 个答案:

答案 0 :(得分:6)

使用isset()确实可以获得更好的性能。不久前我做了一些基准测试,只是隐藏错误的速度大约慢了10倍。

http://garrettbluma.com/2011/11/14/php-isset-performance/

也就是说,性能通常不是PHP的关键因素。什么 个人让我发疯的是 无声错误

当解释者选择不将某些内容标记为错误(这可能导致不稳定)时,这是一个巨大的问题。 PHP特别倾向于

  • 警告关于错误的内容(例如无法连接到数据库)和
  • 发出通知关于应该警告的事情(例如,尝试访问空对象的成员)。

也许我对这种东西过于自以为是,但我之前被这些无声的错误所困扰。 我建议始终在错误报告中包含E_NOTICE。

答案 1 :(得分:3)

你是否应该修理它们当然值得商榷,并且取决于你的情况下的回报;例如,如果代码具有更长的寿命,更多的开发等等,那就更重要了。

一般情况下,假设您的功能将被其他人使用(并且误用)是最佳做法,因此您应该执行isset /!empty / is_object检查以解决此问题。通常,您的代码会发现它是您从未想过的用途和情况。

就性能而言,每次抛出任何类型的错误 - 包括E_NOTICE - 解释器都会旋转错误处理程序,构建堆栈跟踪并格式化错误。关键在于,无论您是否有报告,错误总是会降低执行速度; 因此, 2-3次函数调用以避免E_NOTICE仍然会提高您的性能。< / p>

修改 以上示例的替代方案

我不一定会创建额外的对象来避免错误;你可以优雅地避免它们。以下是几个选项:

1)处理缺失ts的函数:

SpecialClass class {

    funciton getTs () {
        return !empty($this->ts) ? $ts->sec : false;
    }
}

2)处理模板/程序中缺少的ts:

if (!empty($obj->ts->sec)) {
    //do something
}

我特别喜欢empty(),因为您可以使用它来替换{​​{1}},保存多个调用/比较并清空目标var或属性的永不投掷通知。如果你在一个不存在的变量的proptery / member上调用它,它将抛出一个错误。