首先我知道这个问题不止一次出现在这里:
但是我修复所有E_NOTICE(就像人们说你应该的那样)越多,我就越注意到:
举个例子:
假设你使用MongoDB PHP驱动程序,并且在一个类中MongoDate
的类ts
中有一个$obj->ts->sec
对象,该类表示数据库中集合中的单个行。现在你访问这个var就像:ts
但是PHP抛出一个拟合(E_NOTICE),因为在这种情况下ts
本身没有定义为一个对象,因为这个特定的行没有date()
领域。所以你认为这是好的,这是期望的行为,如果它没有设置返回null并且我将在解释器自己的机器人工作之外自己处理它(因为你将它包装在刚刚返回的1970
函数中{ {1}}如果var为null
或none-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
变量)但是,如果您已经测试了代码,并且您知道它是安全的,并且只会以您希望的方式工作,那么修复所有null
或undefined index
错误的重点是什么?是不是在代码中添加了一堆none-object
和2行函数实际上是微优化?
我注意到,在使我的网站符合E_NOTICE标准的一半之后,实际上它现在使用了更多的CPU,内存和时间......所以真正处理每个E_NOTICE错误的重点是什么,而不仅仅是ARE错误?
感谢您的想法,
答案 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上调用它,它将抛出一个错误。