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

Sam*_*aye 5 php error-handling

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

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

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

举个例子:

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

但现在要修复E_NOTICE作为另一个开发人员真的想要我,因为任何E_NOTICE都是terribad并且它使代码变慢,根据错误不做.所以我在被$obj调用的类中创建一个新函数,getTs我给它3行,字面上除了检查tsvar是否是一个MongoDate对象之外什么也不做,如果它是...则返回它

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

class obj{
    public $ts = new MongoDate();
}
Run Code Online (Sandbox Code Playgroud)

我要么必须存储ts内的__constructor(这我不是太高兴要么,我使用了很多的魔法,因为它是),或使用的功能,如果它被设置为检测(我现在做的).

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

  • 未定义的变量
  • 分配未设置的变量(null变量)的属性
  • 不断的错误等

但是,如果你已经测试你的代码,你知道它是安全的,只会工作,你的愿望是所有固定的点的方式undefined indexnone-object错误?是不是isset()在代码中添加了一堆s和2行函数实际上是微优化?

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

谢谢你的想法,

Gar*_*uma 6

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

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

也就是说,性能通常不是PHP的关键因素.什么,亲自开车送我疯狂的是无声的错误.

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

  • 警告应该出错的事情(例如无法连接到数据库)和
  • 问题通知有关的事情,应该警告(如试图访问一个空对象的成员).

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


Bry*_*gee 3

是否应该修复它们当然是有争议的,并且仅取决于您的情况的回报;例如,如果代码有更长的生命周期、更多的开发人员等,那就更重要了。

一般来说,假设您的函数将被其他人使用(和误用)是最佳实践,因此您应该执行 isset/!empty/is_object 检查来解决这一问题。通常,您的代码会发现它进入了您从未打算使用的用途和情况。

就性能而言,每次抛出任何类型的错误(包括 E_NOTICE)时,解释器都会启动错误处理程序,构建堆栈跟踪并格式化错误。关键是,无论您是否让他们报告,错误总是会减慢执行速度;因此,2-3 个函数调用以避免 E_NOTICE 仍会提高您的性能

编辑: 上述示例的替代方案

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

1)处理缺失ts的函数:

SpecialClass class {

    funciton getTs () {
        return !empty($this->ts) ? $ts->sec : false;
    }
}
Run Code Online (Sandbox Code Playgroud)

2)处理模板/过程中丢失的ts:

if (!empty($obj->ts->sec)) {
    //do something
}
Run Code Online (Sandbox Code Playgroud)

我特别喜欢,empty()因为你可以用它来替换 of (isset($var) && ($var or 0 != $var //etc)),保存多个调用/比较,并且 empty 永远不会抛出目标 var 或属性的通知。如果您在不存在的变量的属性/成员上调用它,它将引发错误。