PHP通知抑制;仅某些情况/方法

PHP notice suppression; only certain circumstances/methods

提问人:Dan Lugg 提问时间:8/15/2011 最后编辑:CœurDan Lugg 更新时间:1/13/2019 访问量:121

问:

TL的;dr - 在非常严格的环境中工作时,有没有一种有效的方法来管理PHP的错误报告级别,因为某些流程在不那么严格的级别下会变得更容易?

好;首先,我不认为“错误抑制”是一种解决方案。我(有理由确定我)从未使用过错误抑制运算符,也无意这样做。我利用和(或一些衍生物),并在(面向未来的E_ALL |E_STRICT@set_error_handler()ErrorExceptionerror_reporting(-1))

现在,我不想改变这些习惯,因为我发现它们是一个很好的实践(而且;如果有人有进一步改进我的开发/生产环境设置/实践的建议,我会全神贯注)

但是,当涉及到视图生成时,这可能会变得有点乏味。正确的数据(数组索引、变量等)并不总是可用的,因为控制器无论出于何种原因都无法将某些数据传递到视图。只要此数据对视图生成不重要,视图仍应呈现。

我更喜欢这种语法,因为它不冗长,但(我认为)非常容易理解:

// e() is a shortcut function; given the passed value evaluates to a boolean true
// it will echo() and return true, otherwise it simply returns false
<p><?php e($data['field']) or e('No data found'); ?></p>

当然,如果在没有索引的情况下没有调用 with returned,我们就有问题了。注意 meet 异常,exception meet 脚本失败。$data['field']offsetGet()null

我尝试了不同的实现,包括使用类似节点的类创建数据树来管理传递到视图的数据列表/行。 实际上会创建不存在的节点(在分配或访问时)(以简化节点数据分配,并防止发出通知。__isset() 测试了有效性,但会适当地返回 false它还实现了访问节点数据,并且只会返回缺少的索引。__get()ArrayAccessnull

由于PHP的魔力开销,我选择放弃这个实现(尽管我学到了很多关于重构/优化和分析的知识)

我改用了原生数组,但现在我的观点的代码库中充斥着 ,坦率地说,这很烦人(几乎比上述实现的性能损失还要多isset())

现在,我认为最简单的解决方法是根据我们在脚本中的位置上下滑动缺口:error_reporting()

// View::render()
public function render($data){
    error_reporting(E_ALL & ~E_NOTICE);
    // view generation logic
    error_reporting(-1);
}

但这似乎不是最干净(也不是最安全)的解决方法;尤其是在视图中调用帮助程序函数时。我采用了一种 HMVC 方法,可以从视图发出子请求,因此我需要找到所有逃逸点并用 .render()error_reporting(-1)

我还有其他选择吗?

PHP 处理 报告 错误 抑制 电子通知

评论

0赞 rokdd 8/15/2011
我没有得到你想要的 100%..但也许 php 函数debug_backtrace可能会对您有所帮助
0赞 KingCrunch 8/15/2011
TL的;dr:你应该避免代码,因为代码会抛出任何东西,包括通知。
0赞 Dan Lugg 8/15/2011
@KingCrunch - 是的,是的;这就是为什么我最初选择我的树/节点想法的原因。我已经选择退出性能,但现在处于观望状态。当然,控制器和视图之间的数据完整性和保险将是最佳的,但在这种情况下,我选择了灵活性。

答:

3赞 Arnaud Le Blanc 8/15/2011 #1

即使在视图模板中,“未定义的变量”通知也非常有价值,因为它们有助于发现拼写错误;但这需要定义控制器中的每个变量,或者检查它们是否在视图中设置。

正如你所注意到的,这两个明显的解决方案有一些开销或缺点。即使禁用错误报告也会产生一些开销,因为错误仍然会生成(错误消息被格式化,内部和用户错误处理程序被调用,等等;它们只是隐藏的)。这隐藏了您可能从视图中调用的帮助程序方法的错误;这无助于调试。

我会建议你使用模板引擎。有些生成PHP代码的速度与手写代码一样快。他们会为你处理这个问题,并且会做更多的事情(比如转义,你的视图也应该充斥着htmlspecialchars()调用;))。

评论

0赞 Dan Lugg 8/15/2011
谢谢@user576875 - 我尝试了一些模板引擎,甚至推出了我自己的引擎(一个基于正则表达式,一个基于 DOM),但它们从来没有像普通的 PHP 那么快。对快速的有什么建议吗?(e() 也做转义,它需要比我提到的更多的参数,以及其他帮助函数)
1赞 Don McCurdy 11/1/2014 #2

继续报告E_NOTICE,这是值得的。也就是说,我同意这与未定义的变量的误差口径不同,而且有点丑陋。我从事的一个项目有数千个这样的通知,所以为了继续看到E_NOTICE级别的错误而不被淹没,我实际上重新编译了语言以忽略该特定类型的通知。(我使用的是 HHVM 而不是 PHP,但区别是一样的)。Undefined Indexisset($options['boolean_flag']) && $options['boolean_flag']Undefined Index

是的,这是一个极端的解决方案,但它是一个紧张的选择。显然,您需要在生产环境中使用官方版本。

注意:我写下了重新编译的步骤,如果有人想尝试,可以发布,但这有点超出了原始问题的范围。