关闭或处理生产环境中的错误? [英] Turn off or handle errors within a production environment?

查看:106
本文介绍了关闭或处理生产环境中的错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在与我的团队发生争执之后,因为我们对这种情况有不同的看法..什么时候可以关闭PHP错误消息或抑制某些引发警告的函数,无论出于何种原因,都应注意.

After having an argument with my team because we all have different views on this sort of situation.. When is it actually acceptable to turn off PHP error messages, or to suppress some functions which are throwing warnings, notices for whatever reason..

我知道每个人都说您应该在生产环境中关闭error_reporting,但这可能会导致一些复杂性,而这些复杂性将不会得到解决.因此,没有任何事情会得到解决. PHP带有许多控制错误消息的方法.例如:

I understand everyone says that you should turn off error_reporting within a production environment, but that might cause some complications which will not be picked up.. So nothing will get fixed, furthermore. PHP comes with many different methods to control error messages.. For example:

$Var = "Variable Is Set";

if (@$Var){ echo $Var; }

上方:

if (isset($Var)){ echo $Var; }

因为我们有一个set变量,所以它会成功地回显..而如果我们没有set变量,这将引发一个通知.那么该使用哪个变量呢? isset或错误抑制?

Because we have a set variable, this will sucessfully echo.. Whereas if we didn't have a set variable, this would throw a notice.. So Which one to use? The isset or error suppression?

在生产环境中,使用哪个更可接受?

And within a production environment, which one would be more acceptable to use?

error_reporting(0);

以上内容将关闭所有类型的PHP错误报告,即使遇到任何问题也不会给出错误消息.因此,在某些情况下,这可能会导致代码损坏,由于消息被破坏,代码由于某种未知原因而停止工作

The above will turn off all types of PHP error reporting, giving no error messages even if something is encountered. So in some cases this could lead to broken code that stops working for an unknown reason, due to the message being destroyed

或:

set_error_handler("");

上面的代码启用了一个自定义错误处理程序,该错误处理程序可用于向用户正常显示错误,并使管理人员可以记录详细警告.错误被触发?

The above enables a custom error handler, which can be used to gracefully show a error to the user, and enable administration to log the detailed warning.. But then again, the error_handler to my knowledge will not be called when a fatal error is triggered?

那么我的总体问题?

处理生产环境中的错误还是一般将其关闭?我认为这归结为最佳做法和偏好.但这使我和我的团队感到困惑,甚至是意见分歧.

Handle errors in production environment or just turn them off in general? This boils down to best practices and preferences I guess.. But it's something that is puzzling me and my team to the point of disagreements.

推荐答案

对不起,这不是一个确定的解决方案,但是经过几年的反复试验,我想到了以下实践,这些实践只是我自己的,并且工作得很好:

Sorry, this is not a definite solution, but after several years of trial and error, I came up with the following practices, which are just my own, and work pretty well:

1-切勿使用@来抑制错误.切勿使用任何东西盲目隐藏或忽略所有错误.所有错误都很重要,不应忽略任何错误.

1 - Never use @ to suppress errors. Never use anything to blindly hide or ignore all errors. ALL errors are important, no error should be ignored.

2-按照RafaSashi的建议进行操作,打开错误记录并关闭显示错误.

2 - Do as RafaSashi suggested, turn on error logging and turn off display errors.

3-通过使用PHP.INI中的error_reporting = 2147483647激活所有错误报告.这会使PHP对您可能做错的任何事情都非常挑剔,从而帮助您了解更多信息并及时了解将来的语言弃用和更改.

3 - Activate ALL error reporting, by using error_reporting = 2147483647 in PHP.INI. That will make PHP very picky with anything you may do wrongly, helping you learn more and stay up to date with future language deprecations and changes.

4-您还可以创建自己的错误日志记录,以所需的方式准确记录所需的内容.在手册中查找error_log().如果使用它,甚至可以关闭清除,然后手动开始日志记录,这将使您完全控制PHP的错误日志记录系统.

4 - You can also create you own error logging, to log exactly what you want, the way you want. Look up the manual for error_log(). If you use it, you can even turn looging off, and start logging manually, that will give you full control of PHP's error logging system.

5-我在所有PHP代码中都使用OOP,因此我在所有地方都使用了异常,因此我建议所有人都使用异常.它们比简单的错误处理快了几年.使用此代码可拦截代码中的所有错误并将它们作为异常抛出:

5 - I use OOP in all my PHP code, so I use exceptions everywhere, and I recommend the same for everyone. They're light-years ahead of simply error handling. Use this code to intercept all errors in your code and throw them as exceptions:

set_error_handler('ErrorHandler');
function ErrorHandler($Code, $Message)
{
  throw new Exception($Message, $Code);
}

6-不向用户显示任何错误完全是胡说八道.应该显示一些错误,一些错误应该隐藏,有些应该显示为一般性问题(不要告诉用户确切的问题是什么).

6 - Not showing ANY errors to the user is simply non-sense. Some errors should be shown, some should be hidden, and some should be shown as a generic issue (don't tell the user exactly what the problem is).

a)应显示的错误:由用户引起的所有错误,例如无效的表单输入或错误的行为.这是很明显的,但应该提到.

a) Errors that should be shown: everything caused by the user, like invalid form input or wrong behavior. This is quite obvious, but should be mentioned.

b)应隐藏的错误:仅隐藏您的代码可以处理和纠正的错误.例如,您可以进行数据库连接,如果连接失败,则可以重试.如果第二次尝试成功,请继续,没有人会知道第一次尝试失败.如果需要,只需使用error_log()进行记录.有时,变量尚不存在,因此请使用isset()进行检查,并在需要时对其进行初始化.也无需将其报告为错误.

b) Errors that should be hidden: hide only the errors your code can handle and correct. For example, you can do a DB connection, and if it fails, you can try again. If the second attempt succeeds, go ahead, no one should ever know the first try failed. Just log it if you want, using error_log(). Sometimes, variables don't exist yet, so check this with isset(), and initialize them if needed. No need to report this as an error too.

c)应显示为一般性的错误:大多数错误将属于此类别.您将不会向用户显示PHP内存耗尽,SMTP服务器处于脱机状态或数据库连接被拒绝之类的信息.只需了解如何使用try包装危险代码,使用catch捕获任何错误并将消息转换为可以显示给用户的内容即可.示例:

c) Errors that should be shown as generic: most errors will fall in this category. You will not show the user things like PHP memory exhausted, or that a SMTP server is offline, or that a DB connection was refused. Just learn how to wrap dangerous code with a try, use a catch to capture any error, and convert the message to something you can show to the user. Example:

try
{
  // Dangerous code ahead: we will try to connect to the database, but it 
  // can be offline.
  $mysqli = new mysqli("localhost", "user", "password", "database");
}
catch(Exception $e)
{
  // If we're here, something bad happened during connection. Let's handle it.

  // Notify staff, log error, do anything you can to get someone to quickly 
  // check the issue.
  SendMailAdmin("Database connection Error, check ASAP.");
  error_log("Database connection Error, check ASAP.");

  // And show the user some message. You don't need to tell him about any 
  // detail regarding what truly caused the error.
  die("A problem occurred in our servers. Our technical staff has been notified, 
      please try again in a few minutes.");
}

// If we're here, everything worked fine, so do your DB query and so on....

您可以使用自己认为合适的方法代替die():重新抛出另一个异常,将标头重定向到通用错误消息或任何您想要的内容.

Instead of a die(), you can use what you see fit: re-throw as another exception, do a header redirect to a generic error message or whatever you want.

7-这是更高级的方法,但是您也可以这样做:创建自己的异常层次结构,如下所示:

7 - This is more advanced, but you can do it also: create you own exception hierarchy, like this:

class MVXException extends Exception {}
    class ExMVXDB extends MVXException {}
      class ExMVXDBRead extends ExMVXDB { }
      class ExMVXDBWrite extends ExMVXDB { }
      class ExMVXDBNotFound extends ExMVXDB { }

这是我在自制框架中拥有的异常树的简化.这样做的好处是,如果您执行catch(ExMVXDB $e),则将捕获所有DB错误.但是,如果您只想捕获数据写入操作,则可以执行catch(ExMVXDBWrite $e).

This is a simplification of the exceptions tree I have in my self-made framework. The beauty of this is that if you do a catch(ExMVXDB $e), you will catch ALL DB errors. But if you want to catch only a data writing operation, you can do a catch(ExMVXDBWrite $e).

就是这样.错误处理并不简单,没有直接的答案,但是有很多工具和良好实践可以帮助您选择最适合自己的东西.

That's it. Error handling is not simple, and there's no direct answer, but there are plenty of tools and good practices to help you choose what's best for you.

这篇关于关闭或处理生产环境中的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆