Error handling in PHP

2019-01-10 06:35发布

I'm familiar with some of the basics, but what I would like to know more about is when and why error handling (including throwing exceptions) should be used in PHP, especially on a live site or web app. Is it something that can be overused and if so, what does overuse look like? Are there cases where it shouldn't be used? Also, what are some of the common security concerns in regard to error handling?

9条回答
姐就是有狂的资本
2楼-- · 2019-01-10 06:58

besides handling errors right away in your code you can also make use of

http://us.php.net/manual/en/function.set-exception-handler.php
and
http://us.php.net/manual/en/function.set-error-handler.php

I find setting your own exception handler particularly useful. When an exception occurs you can perform different operations depending on what type of exception it is.

ex: when a mysql_connet call returns FALSE I throw a new DBConnectionException(mysql_error()) and handle it a "special" way: log the error, the DB connection info (host, username, password) etc and maybe even email the dev team notifying them that something may be really wrong with the DB

I use this to compliment standard error handling. i wouldnt recommend overusing this approach

查看更多
爷的心禁止访问
3楼-- · 2019-01-10 06:58

Error suppression with @ is very slow.

查看更多
Ridiculous、
4楼-- · 2019-01-10 07:00

Roughly speaking, errors are a legacy in PHP, while exceptions are the modern way to treat errors. The simplest thing then, is to set up an error-handler, that throws an exception. That way all errors are converted to exceptions, and then you can simply deal with one error-handling scheme. The following code will convert errors to exceptions for you:

function exceptions_error_handler($severity, $message, $filename, $lineno) {
  if (error_reporting() == 0) {
    return;
  }
  if (error_reporting() & $severity) {
    throw new ErrorException($message, 0, $severity, $filename, $lineno);
  }
}
set_error_handler('exceptions_error_handler');
error_reporting(E_ALL ^ E_STRICT);

There are a few cases though, where code is specifically designed to work with errors. For example, the schemaValidate method of DomDocument raises warnings, when validating a document. If you convert errors to exceptions, it will stop validating after the first failure. Some times this is what you want, but when validating a document, you might actually want all failures. In this case, you can temporarily install an error-handler, that collects the errors. Here's a small snippet, I've used for that purpose:

class errorhandler_LoggingCaller {
  protected $errors = array();
  function call($callback, $arguments = array()) {
    set_error_handler(array($this, "onError"));
    $orig_error_reporting = error_reporting(E_ALL);
    try {
      $result = call_user_func_array($callback, $arguments);
    } catch (Exception $ex) {
      restore_error_handler();
      error_reporting($orig_error_reporting);
      throw $ex;
    }
    restore_error_handler();
    error_reporting($orig_error_reporting);
    return $result;
  }
  function onError($severity, $message, $file = null, $line = null) {
    $this->errors[] = $message;
  }
  function getErrors() {
    return $this->errors;
  }
  function hasErrors() {
    return count($this->errors) > 0;
  }
}

And a use case:

$doc = new DomDocument();
$doc->load($xml_filename);
$validation = new errorhandler_LoggingCaller();
$validation->call(
  array($doc, 'schemaValidate'),
  array($xsd_filename));
if ($validation->hasErrors()) {
  var_dump($validation->getErrors());
}
查看更多
beautiful°
5楼-- · 2019-01-10 07:05

Unhanded errors stop the script, that alone is a pretty good reason to handle them.

Generally you can use a Try-Catch block to deal with errors

try
{
    // Code that may error
}
catch (Exception $e)
{
    // Do other stuff if there's an error
}

If you want to stop the error or warning message appearing on the page then you can prefix the call with an @ sign like so.

 @mysql_query($query);

With queries however it's generally a good idea to do something like this so you have a better idea of what's going on.

@mysql_query($query)
    or die('Invalid query: ' . mysql_error() . '<br />Line: ' . __LINE__ . '<br />File: ' . __FILE__ . '<br /><br />');
查看更多
我只想做你的唯一
6楼-- · 2019-01-10 07:10

The best practice IMHO is to use the following approach: 1. create an error/exception handler 2. start it upon the app start up 3. handle all your errors from inside there

<?php

class Debug {

    public static setAsErrorHandler() {
         set_error_handler(array(__CLASS__, '__error_handler'));
    }

public static function __error_handler($errcode, $errmsg, $errfile, $errline) {
       if (IN DEV) {
                print on screen
           }
           else if (IN PRO) {
                log and mail
           } 
    }

}

Debug::setAsErrorHandler();

?>

查看更多
该账号已被封号
7楼-- · 2019-01-10 07:17

You can also use Google Forms to catch and analyse exceptions, without having to maintain a database or publicly accessible server. There is a tutorial here that explains the process.

查看更多
登录 后发表回答