如何在PHP中设计错误报告

如何在PHP中设计错误报告,php,error-handling,Php,Error Handling,我应该如何用PHP编写错误报告模块? 比如说,我想用PHP编写一个函数:“bool isduplicatemail($email)”。 在该函数中,我想检查数据库中是否已经存在$email。 如果存在,它将返回“true”。否则为“假” 现在,查询执行也可能失败,在此期间,我想向用户报告“内部错误” 该函数不应因典型的mysql错误而消亡:die(mysql_error()。我的web应用程序有两个界面:浏览器和电子邮件(您可以通过发送电子邮件执行某些操作)。 在这两种情况下,它都应以良好的方式

我应该如何用PHP编写错误报告模块? 比如说,我想用PHP编写一个函数:“bool isduplicatemail($email)”。 在该函数中,我想检查数据库中是否已经存在$email。 如果存在,它将返回“true”。否则为“假”

现在,查询执行也可能失败,在此期间,我想向用户报告“内部错误”

该函数不应因典型的mysql错误而消亡:die(mysql_error()。我的web应用程序有两个界面:浏览器和电子邮件(您可以通过发送电子邮件执行某些操作)。 在这两种情况下,它都应以良好的方式报告错误。 我真的必须为此使用异常处理吗


有谁能告诉我一些好的PHP项目,在那里我可以学习如何设计健壮的PHP web应用程序吗?

使用MVC,我总是使用某种默认的错误/异常处理程序,在那里可以捕获带有异常(并且没有自己的错误-/exceptionhandling)的操作。

在那里,您可以决定通过电子邮件或浏览器响应进行答复,并且它的外观始终相同:)

我会使用像Zend framework这样的框架,它具有完整的异常处理机制。

查看php手册。同时阅读底部的评论,非常有用


在这些页面中还介绍了如何将PHP错误转换为异常的方法,因此您只处理异常(大部分)。

在我的PHP项目中,我尝试了几种不同的方法。我得出了以下对我来说似乎很有效的解决方案:

首先,我编写的任何主要PHP应用程序都有某种中央单例,用于管理应用程序级数据和行为。“应用程序”对象。我在这里提到这一点是因为我使用这个对象来收集其他模块生成的反馈。渲染模块可以查询应用程序对象,以获取它认为应该向用户显示的反馈

在较低的级别上,每个类都派生自包含错误管理方法的基类。例如,“AddError(code,string,global)”和“GetErrors()”以及“ClearErrors”。“AddError”方法做两件事:将该错误的本地副本存储在该对象的实例特定数组中,并(可选地)通知应用程序对象该错误(“全局”是布尔值),然后存储该错误以供将来在渲染中使用

下面是它在实践中的工作原理:

请注意,“Object”定义了以下方法:AddError ClearErrors GetErrorCodes GetErrorsAsString GetErrorCount和HasError(为方便起见)

// $GLOBALS['app'] = new Application();

class MyObject extends Object
{
     /**
      * @return bool Returns false if failed
      */
     public function DoThing()
     {
          $this->ClearErrors();
          if ([something succeeded])
          {
              return true;
          }
          else 
          {
              $this->AddError(ERR_OP_FAILED,"Thing could not be done");
              return false;
          }              
     }
}

$ob = new MyObject();
if ($ob->DoThing()) 
{
   echo 'Success.';
}
else 
{
   // Right now, i may not really care *why* it didn't work (the user
   // may want to know about the problem, though (see below).
   $ob->TrySomethingElse();
}

// ...LATER ON IN THE RENDERING MODULE
echo implode('<br/>',$GLOBALS['app']->GetErrorsAsStrings());
/$GLOBALS['app']=新应用程序();
类MyObject扩展对象
{
/**
*@return bool如果失败则返回false
*/
公共函数DoThing()
{
$this->ClearErrors();
如果([某事成功])
{
返回true;
}
其他的
{
$this->AddError(ERR_OP_失败,“事情无法完成”);
返回false;
}              
}
}
$ob=新的MyObject();
如果($ob->DoThing())
{
呼应‘成功’;
}
其他的
{
//现在,我可能真的不在乎*为什么*它不起作用(用户)
//但是,您可能想知道这个问题(请参见下文)。
$ob->TrySomethingElse();
}
//…稍后在渲染模块中
echo内爆(“
,$GLOBALS['app']->getErrorsAsString());
我喜欢这一点的原因是:

  • 我讨厌异常,因为我个人认为它们使代码变得更加复杂
  • 有时候你只需要知道一个函数成功或失败,而不是出了什么问题
  • 很多时候,您不需要特定的错误代码,但需要特定的错误字符串,并且不希望为每个可能的错误条件创建错误代码。有时,您真的只想使用“opfailed”代码,但为了用户的利益而在字符串本身中详细说明。这允许这种灵活性
  • 有两个错误收集位置(本地级别供调用算法使用,全局级别供渲染模块用于告诉用户有关它们的信息)对我来说非常有用,可以为每个功能区域提供完成任务所需的准确信息

  • +业务逻辑的每个接口都应该处理错误的显示和响应。让它抛出“DuplicateException”,电子邮件/Web ui会捕捉到它,并根据需要将其更改为HTML或Mime消息。快速失败,严重崩溃。例外情况是您的朋友。他们会清除这些困扰您的主应用程序的大量错误检查。如果您必须向用户隐藏错误并显示一个漂亮的页面,请使用全局捕获程序。我不确定是哪一个大规模错误“检查”您指的是,但事实是,您可以使用这两种方法生成非常糟糕的代码和非常好的代码,从而担心在您调用的每个函数上返回FALSE或NULL或-1,并对其进行适当的处理。然后,在您的代码中,您会忘记检查它们,从而导致无提示错误或应用程序崩溃G20行之后,很难调试。事实上,它只是假的或是真的,处理它的灵活性正是它的好处。如果我理解正确的话,异常要复杂得多,因为你可以抛出任何类型的异常,甚至可以在当前函数中处理它。非常混乱的Imhot我相信例外是被美化的goto语句。虽然我不会走那么远,但我会说这会使遵循代码变得困难。不过我认为这是相当主观的。那么一切都是goto语句。嗯。我猜你是说每个表达式都会导致下一个表达式?我想这有点误解了我的意思考虑抛出的异常不仅可以将您发送到同一函数的另一部分,而且如果未正确处理,则完全发送到应用程序的另一部分。