草庐IT

php - 这种处理PHP错误的方法是否有任何 "gotchas"?

coder 2024-04-08 原文

我是 PHP 的新手,但在我看来 PHP 的错误处理有点贫民窟,错误和警告穿插在异常中(不要让我开始使用 die() )。因此,我不确定如何最好地创建、解释和处理我的应用程序中的所有错误情况。

我的总体攻击计划大致如下:

  1. 将所有警告/错误转换为异常,使用 set_error_handler() 来包装错误。
  2. 防御性编码,先发制人地检查我预计会出错的地方。只有当我不能直接处理错误时才抛出异常。通常的 try/catch block 将在需要时就位,以处理我自己不会抛出的异常。
  3. 将我的整个应用程序(即我的 index.php 入口文件)包装在它自己的 try/catch 中。如果失败,我将抛出一个 HTTP 500 并显示一个合适的错误页面。大概这个页面将是一个单独的、预编译的文件,而不是包含页眉/正文/页脚的集合——这主要是为了让我仍然可以覆盖奇怪的异常,比如乱码模板文件。我想这就是为什么 Google 的 500 级错误页面看起来与他们推出的其他所有内容有很大不同的原因。
  4. 作为 #2 和 #3 的必然结果,因为我希望预先处理所有事情,如果我决定抛出我自己的异常,我也希望不会捕获错误,而是让它一直冒泡到我的顶级处理程序。这里的想法是,如果我无法在它发生时处理它,那么我可能没有能力在其他任何地方处理它。我正在考虑为这些错误提供它们自己的子类 - 也许是 CriticalErrorException - 可以直接在我的日志中识别/生成电子邮件,以便我可以快速查看它。总的来说,我希望这些事情可能在开发中发生,但应该在生产中解决。
  5. 任何到达顶部的错误都会记录在数据库中,并故障转移到日志文件。如上所述,严重错误会触发一封电子邮件。如果报告故障转移到文件 - 即存在数据库错误 - 这也会触发一封电子邮件。

我认为这很好地涵盖了大多数情况,但正如我所说,我是 PHP 的新手,所以我不知道是否有我忽略的极端情况或奇怪的行为。

我的计划有什么缺陷?我怎样才能克服它们?

最佳答案

总的来说,让意外异常冒泡到顶部 catch block 然后提供 HTTP 500 的策略很好(许多框架就是这样做的)。

我不太同意制作一个CriticalErrorException——也许您现在不希望捕获某些东西,但您可能会在将来扩展您的错误处理(可能面对额外的申请要求)。随便扔什么都是自然的。在大多数情况下,一个简单的 Exception 就可以了。

关于 PHP 错误:您不需要严格地将 E_ERROR 转换为异常(它无论如何都会终止您的应用程序,并且还会显示在错误日志中)。不过,您最好处理 E_NOTICE,因为通知几乎总是意味着代码有问题。

最后,当谈到引发警告的 PHP 函数时,我会这样说:

// Assume that php_function() raises E_WARNING and returns FALSE on error
// WARNING: if you have defined a custom error handler, IT WILL STILL BE CALLED
//          even though the @ operator suppresses the error
$result = @php_function($argument); // suppress error
if (!$result) {
    // error handling here
}

而不是这个:

try {
    $result = php_function($argument);
}
catch (Exception $ex) {
    // error handling here
}

原因是当您打算立即对错误使用react时,转换为异常并不能真正给您带来任何好处。相反,如果需要有关其错误处理策略的更多信息,第一个代码片段将“告诉”阅读它的开发人员查找 php_function 的文档。第二个代码片段将要求开发人员了解在您的应用中具体实现的错误处理。

更新:

我并不是说您应该使用 @ 来忽略函数调用产生的错误。我的意思是,当使用以这种方式运行的遗留 PHP 函数时,并且当您完全准备好处理错误并从中恢复时,当然不应再将其视为有关应用程序执行的“错误”。 在这种特定情况下,我建议抑制它,以免它也被报告。

关于php - 这种处理PHP错误的方法是否有任何 "gotchas"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4296807/

有关php - 这种处理PHP错误的方法是否有任何 "gotchas"?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  5. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  6. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  7. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  8. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  9. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  10. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

随机推荐