Divide PHP errors and Application Errors

2019-04-15 01:41发布

问题:

I'm working on an Application and a question occurred. I was thinking of letting PHP errors a side (they would be log in the database or in a file) and manage other errors (such as "Your username is not valid" or "Your typed the wrong password" or "The image could not be loaded") with the so famous try-catch method. Is it good to completely manage this kind of errors only with try-catch?

回答1:

The main advantage of exceptions is it's behavior of "petite mort", a local die() inside try{} block, preventing further code from execution.

While it's quite handy in handling application errors, it become not so good when dealing with validating user input. If a user made 3 mistakes filling a form, it would be merciful to show them all at once, not one after another.

You rather need POST/Redirect/GET pattern to handle user errors:

<?  
if ($_SERVER['REQUEST_METHOD']=='POST') {  

  $err = array();
  //performing all validations and raising corresponding errors
  if (empty($_POST['name']) $err[] = "Username field is required";  
  if (empty($_POST['text']) $err[] = "Comments field is required";  

  if (!$err) {  
    //if no errors - saving data and redirect
    header("Location: ".$_SERVER['PHP_SELF']);
    exit;
  }  else {
    // all field values should be escaped according to HTML standard
    foreach ($_POST as $key => $val) {
      $form[$key] = htmlspecialchars($val);
    }
} else {
  $form['name'] = $form['comments'] = '';  
}
include 'form.tpl.php';
?>  


回答2:

I think: It is not, because this are not errors, or exception, but simply invalid input. They are also quite common and in this context not an exception in the meaning of the word.

On the other hand, because every exception breaks the current execution, it may lead to unexpected behaviour, when some code is not executed, just because someone entered an unknown username or something. In case of errors, or exceptions, you usually want to stop the execution, because you assume that the execution is not (reasonable) possible (until you catch the exception and go on).



回答3:

For enduser errors you should introduce a separate application level handling system.

Exceptions are useful for handling error conditions (errors that arise on production), while custom E_USER_ errors are the best fit for signaling data/debug/security issues (anything that should be handled at development stage).



回答4:

I use a custom Log class I wrote, and set it up as the default error handler and exception handler, as well as providing "debug", "info", "warning", "success" and "deprecated" methods for manually logging (and optionally displaying) messages.

The bonus is, it shows a dump of the variables in the current scope when an actual error occurs, rather than just telling you where it occurred.



回答5:

Errors and exceptions are a technical matter while validation it's business mater. IFs handle Business, TRY/CATCH handles technical stuff they do not mix and you should not mix them. There are times when you must use an if which throws an exception (PHP stuff) but that is the necessity at framework/architecture level for example

if(database_error_handle_raises_error()) {
     throw new MyDatabaseException(driver_raised_error);
}

this way you can better control the errors. But the rule stays: Try/Catch/Throw = technical If/Else Switch = business