Is it possible to handle PHP errors via code?

14

As everyone knows, PHP returns runtime syntax errors in the browser, such as fatal errors and exceptions.

Is it possible to handle these errors via code so that I can save to the database in an error log table?

The need is because I use a PHP file to receive external POST and if I miss the syntax or throw some exception in this file, I will not know how and where it occurred.

    
asked by anonymous 03.10.2014 / 19:38

3 answers

9

Note that depending on the error, the execution of the script will be interrupted. If at any time DB has stopped and generated an error, you will not be able to generate the LOG, so usually the LOGs are written in a simple TXT, with date-time, file, line, code and message.

Basically you need to use these 3 functions below. They catch all types of errors and fire a Exception which will be where you receive the error information and generates the LOG.

(register_shutdown_function) sub>

Registers a function to execute at the end of execution. Its myLog fault function when executed can check for errors using error_get_last()

function myLog()
{
    if( ! is_null( $error = error_get_last() ) )
    {
        // obtendo informações do erro e disparando uma Exception
        extract( $error , EXTR_SKIP );
        new Exception( $message , $type , 0 , $file , $line );
    }
}

register_shutdown_function( 'myLog' );

(set_exception_handler) sub>

Defines a user role for handling exceptions. Usually when an exception is fired without capture. Your $exception variable is an object and contains class properties with errors, you can take a look at the DOC Exception

function myException( $exception )
{
    // mensagem de erro, grave um TXT-LOG com os dados do erro
    echo '<h2>Error</h2><h3>Mensagem:</h3><pre>' . $exception->getMessage() . '</pre>
          <h3>Arquivo:</h3><pre>' . $exception->getLine() . '</pre>
          <h3>Linha:</h3><pre>' . $exception->getLine() . '</pre>
          <h3>Código:</h3><pre>' . $exception->getCode() . '</pre>';
}

set_exception_handler( 'myException' );

(set_error_handler) sub>

Defines a user's role to handle errors. When an error occurs, its function will identify and generate a log or trigger an exception that will be captured by its function above myException .

function log_error( $code , $error , $file , $line )
{
    // obtendo informações do erro e disparando uma Exception
    if( error_reporting() === 0 ) return;
    new Exception( $error , $code , 0 , $file , $line );
}

set_error_handler( 'log_error' );
    
03.10.2014 / 19:51
5

Use set_error_handler and register_shutdown_function to log the problems.

A few months later I realized that I had several problems working with more than one developer (an average team), there were several errors that happened, so I made a code for it.

Try this (to save on files), include on all pages:

<?php
class getErrors
{
    static private $folder = 'data/erros/'; //Configure a pasta
    static private $writeOk = false;

    static public function writeErros($e) {//Erro personalizado
        if (self::$writeOk === true) {
            return NULL;
        }

        self::$writeOk = true;

        $log = fopen(self::$folder . gmdate('d-m-Y_H') . '-GMT.html', 'a+');

        if ($log) {
            $req = $_SERVER['HTTP_HOST'] . (
                isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : $_SERVER['PHP_SELF']
            );
            fputs($log,
                '<meta http-equiv="Content-Type" content="text/html;">' .
                '<h1>Erro: ' . $e['message'] . '</h1>' .
                '<p>Página: <a href="http://' . $req . '">http://' . $req . '</a></p>' . 
                (isset($_SERVER['HTTP_REFERER']) === false ? '' : (
                    $_SERVER['HTTP_REFERER'] !== '' ? ('<p>Referer: <a href="' . $_SERVER['HTTP_REFERER'] . '">' . $_SERVER['HTTP_REFERER'] . '</a></p>') : ''
                )).
                '<p>Linha: ' . $e['line']  .
                '<p>Arquivo: ' . $e['file']  .
                '<p>$_SERVER:<p><pre>' .
                print_r($_SERVER, true) . '</pre>' .
                '<p>$_GET:<p><pre>' .
                print_r($_GET, true) . '</pre>' .
                '<p>$_POST:<p><pre>' .
                print_r($_POST, true) . '</pre>' 
            );
            fclose($log);
        }
    }

    static public function putLastError() {
        $e = error_get_last();
        if (NULL !== $e) {
            self::writeErros($e);
        }
    }

    static public function handleErr($tipo, $errstr, $errfile, $errline, $detail) {
        self::writeErros(
            array(
                'message' => $tipo . ': ' . $errstr,
                'line'    => $errline,
                'file'    => $errfile
            )
        );
        return false;
    }
}

set_error_handler(array('getErrors', 'handleErr'), E_ALL|E_STRICT); //Configura a classe para o "handle"
register_shutdown_function(array('getErrors', 'putLastError')); //usar 'error_get_last', geralmente em erros "fatais"
  

Note: The writeErros function captures the variables used in the request so you can get an idea of what situation the problem occurred

    
03.10.2014 / 19:52
1

You can define a function as callback if there are errors.

set_error_handler()

link

function LogErro($errno, $errstr, $errfile, $errline)
{
    //o que quiser...
}

set_error_handler("LogErro");

The LogErro () function will always be called when there are errors or warnings, and you have the error data in it to be able to handle them. See the explanation of the variables:

$ errno Error level in int

$ errstr Explanation of error

$ errfile File where the error occurred

$ errfile Line where the error occurred

    
03.10.2014 / 19:56