views:

62

answers:

3

My site is completely custom, as such I like to know when I have poorly written code. I use set_exception_handler and set_error_handler to use custom classes to log errors to a file. This includes notices and warnings.

Within my own code, this is fine as I get very few logs and those that I do get are things I actually want to fix.

However, i've just started using simplePie and because it's PHP4 compatible I get tons of notices, primarily for things like calling functions statically or passing things by reference incorrectly.

It's too much for me to go through and fix simplePie, if it wasn't I wouldn't be using it in the first place.

Is there a way that I can specifically ignore errors generated by a certain file or class? Here's an overview of what of my very basic exception handling looks like:

    set_exception_handler("CustomExceptionHandler");
    set_error_handler("customErrorHandler");

    /**
     * CustomExceptionHandler()
     *
     * This is used if an exception is thrown that isn't caught.
     *
     * @param   object  $e  The exception as an object
     */
    function CustomExceptionHandler(Exception $e) {
        exitToError($e->getMessage());
    }

    /**
     * customErrorHandler()
     *
     * This is called for any errors no matter what their level.
     */
    function customErrorHandler($errno, $errstr, $errfile, $errline) {
        if(in_array($errno, array(E_USER_ERROR, E_RECOVERABLE_ERROR))) {
            throw new CustomErrorException($errstr, 0, $errno, $errfile, $errline);
        } else {
            CustomException::logError($errstr, $errno, $errfile, $errline);
        }
        return FALSE;
    }

/**
     * class CustomErrorException
     *
     * Used by custom_error_handler() to convert all fatal
     * errors to exceptions.
     *
     * @see custom_error_handler()
     * @see http://www.php.net/manual/en/class.errorexception.php
     */
    class CustomErrorException extends CustomException {
        /**
         * $severity
         *
         * The severity level of the exception
         *
         * @access  protected
         * @var     int
         */
        protected $severity;

        /**
         * __construct()
         *
         * Constructs the new exception
         *
         * @access  public
         * @param   string  $message    The Exception message
         * @param   int     $code       The Exception code
         * @param   int     $severity   The severity level of the exception
         * @param   string  $filename   The filename where the exception was thrown
         * @param   int     $lineno     The line number where the exception was thrown
         */
        public function __construct($message, $code = null, $severity = E_ERROR, $filename = null, $lineno= null) {
            $this->message  = $message;
            $this->code     = $code;
            $this->severity = (int)$severity;
            $this->file     = $filename;
            $this->line     = $lineno;

            self::logError($this->message,$this->code,$this->file,$this->line,$this->getTraceAsString());
        }
    }

    /**
     * class CustomException
     *
     * Overwrites Exception to give us more control on how
     * exceptions are handled and logged.
     *
     * @see http://www.php.net/manual/en/language.exceptions.extending.php
     */
    class CustomException extends Exception {

        /**
         * __construct
         *
         * We call the parent contruct as we still want it to do all its magic. We just want
         * overwrite this method so that we can log the error exactly how we want.
         */
        public function __construct($message, $code = 0, Exception $previous = NULL) {
            parent::__construct($message, $code);
            self::logError($this->getMessage(),$this->getCode(),$this->getFile(),$this->getLine(),$this->getTraceAsString());
        }

        /**
         * __toString()
         *
         * We overwrite this function so that we can use our stringBuilder function.
         */
        public function __toString() {
            return self::stringBuilder($this->getMessage(),$this->getCode(),$this->getFile(),$this->getLine(),$this->getTraceAsString());
        }

        /**
         * stringBuilder()
         *
         * We use this method so that we have a standard method of building error
         * strings that anything can tap into.
         *
         * @access  public
         * @param   string  $message    the exception message
         * @param   int     $code       the code assigned to this exception
         * @param   string  $file       the file where the exception occurred
         * @param   int     $line       the line where the exception occurred
         * @param   string  $trace      backtrace
         */
        public function stringBuilder($message, $code, $file, $line, $trace='') {
            //return "[".date("d-M-Y H:i:s")."] ".$this->getMessage()." in ".$this->getFile().":".$this->getLine()."\nStack trace:\n".$this->getTraceAsString()."\n";
            return "[".date("d-M-Y H:i:s")."] ".$message." in ".$file.":".$line."\n";
        }

        /**
         * logError()
         *
         * We use a method so that we have a standard way of saving errors
         * to a log.
         *
         * We use XML because it's easy to parse.
         *
         * @access  public
         * @param   string  $message    the exception message
         * @param   int     $code       the code assigned to this exception
         * @param   string  $file       the file where the exception occurred
         * @param   int     $line       the line where the exception occurred
         * @param   string  $trace      backtrace
         * @todo    We could improve it to write to the xml file using DomDocument
         *          as laid out here http://www.xml-training-guide.com/append-delete-data-from-xml-using-php.html
         */
        public function logError($message, $code, $file, $line, $trace='') {
            //Save it to a standard text file to guarentee saving the error
            file_put_contents(ROOT_URL.ERROR_LOG_TXT,self::stringBuilder($message, $code, $file, $line, $trace),FILE_APPEND);
        }
    }

and here is an example of two of the errors simplePie throws up:

[01-Aug-2010 00:50:33] Assigning the return value of new by reference is deprecated in ***\SimplePie.php:738
[01-Aug-2010 00:50:34] Non-static method SimplePie_Misc::parse_date() should not be called statically in ***\SimplePie.php:60
A: 

You have to remove these errors.
1. Remove & in assignments like $foo =& new Object()
2. You can't access method in statticly way if it's not a static method so instead Object::method() you should try using Object->method() or try to change function method() to static function method()

Or the best solution - try to find library in php5

tuffkid
-1, while I do agree with finding a library written in php5, the OP _does_ state that it's too much of a hassle to go through and fix a whole library, especially if it works perfectly well otherwise.
Carson Myers
+3  A: 

Is there a way that I can specifically ignore errors generated by a certain file or class?

Should be easy! You could check in your custom error handler

function customErrorHandler($errno, $errstr, $errfile, $errline)

whether $errfile is in one of the simplePie files, and in that case return true; silently.

Pekka
I was going to suggest the same. Beat me to it.
Gordon
The answer was so obvious I can't believe I didn't actually see it. This is actually even better as I have all my third party classes in a "3rdparty" folder. So I can just ignore all warnings and notices from this folder, whilst still getting errors. A perfect solution.Clearly it's just too early in the morning for me right now :D
Rob
A: 

You could inspect the $errfile parameter passed to your error handler to see if the error originates from somewhere inside simplePie. Documentation: http://php.net/manual/en/function.set-error-handler.php

tdammers