SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 36
  1. #1
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Predefined exceptions

    When listing the result of the get_declared_classes(), I get quite a lot of already defined Exception classes: ErrorException, ReflectionException, LogicException, BadMethodCallException etc.

    Does anyone know where these exceptions come from and when (and from where) are they thrown?

  2. #2
    SitePoint Wizard Ren's Avatar
    Join Date
    Aug 2003
    Location
    UK
    Posts
    1,060
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Most of them are defined in the SPL extension, so I'd bet they're limited to SPL, if they are used at all in PHP internals.

  3. #3
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Indeed they are, thanks. Although I still cannot find the one that interests me most, the ErrorException...

  4. #4
    SitePoint Guru
    Join Date
    Nov 2002
    Posts
    841
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You can use the reflection API to find out where they were defined.

  5. #5
    SitePoint Wizard Ren's Avatar
    Join Date
    Aug 2003
    Location
    UK
    Posts
    1,060
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Oh, http://www.ren.dotgeek.org/classbrow...ErrorException , looks like someone wants to replace PHP notices/warnings/errors (I presume thats what the severity property signifies) with an exception?

  6. #6
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

  7. #7
    SitePoint Zealot crashmakerMX's Avatar
    Join Date
    Jun 2005
    Location
    Germany
    Posts
    129
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by BerislavLopac
    What more can I say? Cool!

  8. #8
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Berislav, could you please elaborate on how this can handle fatal errors. The following doesn't work for me (5.1.2):

    PHP Code:
    function exceptions_error_handler($severity$message) {
        throw new 
    ErrorException($message0$severity);
    }
    set_error_handler('exceptions_error_handler');

    try {
        
    notReally();
    } catch(
    Exception $e) {
        
    var_dump($e);


  9. #9
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Uhhh, my mistake -- it still won't handle fatal errors, even though I think it should. (I tested with code which produces a warning level error, while I mistakenly believed it's a fatal error.)

    I still think that it would be a useful addition to PHP -- on par with Namespaces -- and that there shouldn't be that much work to implement a php.ini switch that would by default (i.e. without a custom error handler) throw an ErrorException (except, of course, for the unhandled exception error).

  10. #10
    SitePoint Member
    Join Date
    Jan 2006
    Location
    Norway
    Posts
    18
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Post A quick notice on php's ErrorException:

    If you use the function suggested above:
    PHP Code:
    <?php
    function exceptions_error_handler($severity$message) { 
        throw new 
    ErrorException($message0$severity); 

    set_error_handler('exceptions_error_handler'); 

    try { 
        
    notReally(); 
    } catch(
    Exception $e) { 
        echo 
    $e->getFile();
        echo 
    $e->getLine();
    }
    ?>
    The catch block will print out the line and file the Exception was thrown.

    In other words where the exceptions_error_handler() function is implemented

    However if you extend the exceptions_error_handler() function like this:
    PHP Code:
    function exceptions_error_handler($severity$message$filename$lineno) {
        throw new 
    ErrorException($message0$severity$filename$lineno);

    The catch block will then print out the line and file where the error happened.

    ErrorException is defined with this parameters
    PHP Code:
    ErrorException([string $exception [, long $code, [ long $severity, [ string $filename, [ long $lineno ]]]]]) 

  11. #11
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nice Fjoggen. I have been using my own implementation of ErrorException because of that - I didn't realize that it was possible to pass the file + linenumber in the constructor.
    It's really odd that this class isn't documented anywhere - not even on the SPL site (where I suppose it belongs?)

  12. #12
    SitePoint Wizard Ren's Avatar
    Join Date
    Aug 2003
    Location
    UK
    Posts
    1,060
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    Nice Fjoggen. I have been using my own implementation of ErrorException because of that - I didn't realize that it was possible to pass the file + linenumber in the constructor.
    It's really odd that this class isn't documented anywhere - not even on the SPL site (where I suppose it belongs?)

    ErrorException is part of ZendEngine2 it seems, and not SPL.

    /* {{{ proto ErrorException::__construct(string message, int code, int severity [, string filename [, int lineno]])
    ErrorException constructor */
    ZEND_METHOD(error_exception, __construct)

    from ZendEngine2/zend_exceptions.c

  13. #13
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Looks like there's some confusion in this thread. At the moment there is no magic behind ErrorException and there is nothing you cannot do in pure php, like this
    PHP Code:
    class ErrorException extends Exception {
        function 
    __construct($message null$code 0$severity 0$file ''$line){
            
    parent::__construct($message$code);
            
    $this->severity $severity;
            
    $this->file $file;
            
    etc etc etc 
    ErrorException is indeed a part of php core but I fail to see any reason why it should be there.

  14. #14
    SitePoint Member
    Join Date
    Jan 2006
    Location
    Norway
    Posts
    18
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The magic behind ErrorException is that you can use it to catch php errors such as E_NOTICE E_WARNING (does not work on fatal errors) without having to write your own error_handler class.

    Your example is valid, but why do the extra work?

  15. #15
    SitePoint Zealot sleepeasy's Avatar
    Join Date
    Sep 2003
    Location
    Bristol, UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Usually you don't want to generate an exception when using the error supressor operator (@) as it rather defeats the purpose of the operator:

    PHP Code:
    function error_to_exception($severity$message$file$line) {
        if (
    error_reporting() != 0) {
            throw new 
    ErrorException($message0$severity$file$line);
        }
    }

    set_error_handler('error_to_exception');

    $foo = array();
    $tmp = @$foo[0]; 
    Always open to question or ridicule

  16. #16
    SitePoint Wizard Ren's Avatar
    Join Date
    Aug 2003
    Location
    UK
    Posts
    1,060
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    set_error_handler() takes a 2nd parameter for the severity levels to call the function on.

    Perhaps something like ..
    PHP Code:
    set_error_handler('errorToExceptionHandler'E_ALL & ~(E_NOTICE|E_USER_NOTICE|E_STRICT)); 

  17. #17
    SitePoint Zealot sleepeasy's Avatar
    Join Date
    Sep 2003
    Location
    Bristol, UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    True, however, to my knowledge there's no way to prevent an error handler being called by an @supressed error, because the error type produced is the same as if the @ wasn't present.

    PHP Code:
    // Accessing an undefined array index produces E_NOTICE

    $foo = array();
    $tmp $foo[0]; // I want to call my error handler (+ generate exception) here
    $tmp = @$foo[0]; // But not here 
    Correct me if I'm wrong, but your example wouldn't call my error handler if I did

    PHP Code:
    $foo = array();
    $tmp $foo[0]; 
    Always open to question or ridicule

  18. #18
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by sleepeasy
    True, however, to my knowledge there's no way to prevent an error handler being called by an @supressed error, because the error type produced is the same as if the @ wasn't present
    Not true. Errors generated where @ was used get the severity rating of 0. Here's a simple debug handler that takes advantage of that fact:
    PHP Code:
    /**
     * Error handler, providing rigorous backtrace information.
     * @param    int        error type
     * @param    string    error message
     * @param    string    file name
     * @param    string    line number
     */
    function ErrorHandler ($error_type$error_message$file$line)
    {
        static 
    $error_types = array
            (
                
    1        => 'E_ERROR',            2        => 'E_WARNING',
                
    4        => 'E_PARSE',            8        => 'E_NOTICE',
                
    16         => 'E_CORE_ERROR',        32        => 'E_CORE_WARNING',
                
    64         => 'E_COMPILE_ERROR',    128        => 'E_COMPILE_WARNING',
                
    256        => 'E_USER_ERROR',        512        => 'E_USER_WARNING',
                
    1024    => 'E_USER_NOTICE',        2047    => 'E_ALL',
                
    2048    => 'E_STRICT'
            
    );
        
    /**
         * Check error type against error reporting level. @ is always ignored.
         */
        
    if (($error_type != 0) && ($error_type ini_get('error_reporting')))
        {
            echo 
    "<strong>".$error_types[$error_type]."</strong>: {$error_message}<br />\n";
            echo 
    "In <strong>$file</strong> ";
            echo 
    "on line <strong>$line</strong><br />\n";
            echo 
    "<p>Backtrace:</p><pre>";
            
            
    $backtrace debug_backtrace();
            
    // First is always ErrorHandler, skip it
            
    array_shift($backtrace);
            
    $i = -1;
            foreach (
    $backtrace as $trace)
            {
                
    $args = array();
                if (isset(
    $trace['args']))
                {
                    foreach (
    $trace['args'] as $a)
                    {
                        switch (
    gettype($a))
                        {
                            case 
    'integer':
                            case 
    'double':
                                     
    $args[] = $a;
                            break;
                            case 
    'string':
                                    
    $a htmlspecialchars(substr($a064)).((strlen($a) > 64) ? '&hellip' '');
                                    
    $args[] = "\"$a\"";
                            break;
                            case 
    'array':
                                    
    $args[] = 'Array('.count($a).')';
                            break;
                            case 
    'object':
                                    
    $args[] = 'Object('.get_class($a).')';
                            break;
                            case 
    'resource':
                                    
    $args[] = 'Resource('.strstr($a'#').')';
                            break;
                            case 
    'boolean':
                                    
    $args[] = $a 'True' 'False';
                            break;
                            case 
    'NULL':
                                    
    $args[] = 'NULL';
                            break;
                            default:
                                    
    $args[] = 'UNKNOWN';
                        }
                    }
                }
                
                echo 
    '#'.++$i.' ';
                echo 
    $trace['file'].'('.$trace['line'].'): ';
                echo (isset(
    $trace['class'])    ?    $trace['class'].$trace['type']    :    '');
                echo 
    $trace['function'].'('.implode(', ',$args).')';
                echo 
    "\n";
            }
            echo 
    '#'.++$i." {main}</pre>";
        
            exit;
        }


  19. #19
    SitePoint Zealot sleepeasy's Avatar
    Join Date
    Sep 2003
    Location
    Bristol, UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Ezku
    Not true. Errors generated where @ was used get the severity rating of 0
    Well...

    PHP Code:
    function test_handler($severity$message$file$line) {
        echo 
    $severity ' (line ' .  $line ')<br/>';
    }

    set_error_handler('test_handler');

    echo 
    $foo;
    echo @
    $foo
    will produce:

    8 (line 8)
    8 (line 9)
    --

    error_reporting gets set to 0 (temporarily), and $severity is never 0, which is why your code works.
    Always open to question or ridicule

  20. #20
    SitePoint Wizard Ren's Avatar
    Join Date
    Aug 2003
    Location
    UK
    Posts
    1,060
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, would need the additional check for @ usage, for times when forced to use it.

    PHP Code:
    <?php

    function errorToExceptionHandler($severity$message$file$line)
    {
        if (
    error_reporting() & $severity)
            throw new 
    ErrorException($message0$severity$file$line);
    }

    set_error_handler('errorToExceptionHandler');

    $foo = array();

    error_reporting(E_ALL);                          // Throw exceptions on all..
    $tmp = @$foo[0];                                 // But this is suppressed 

    error_reporting(E_ALL & ~E_NOTICE);       // Don't throw exceptions on notices
    $tmp $foo[0];

    $a 0;

  21. #21
    SitePoint Wizard Ren's Avatar
    Join Date
    Aug 2003
    Location
    UK
    Posts
    1,060
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog
    Looks like there's some confusion in this thread. At the moment there is no magic behind ErrorException and there is nothing you cannot do in pure php, like this
    PHP Code:
    class ErrorException extends Exception {
        function 
    __construct($message null$code 0$severity 0$file ''$line){
            
    parent::__construct($message$code);
            
    $this->severity $severity;
            
    $this->file $file;
            
    etc etc etc 
    ErrorException is indeed a part of php core but I fail to see any reason why it should be there.
    A custom Exception wouldn't work the same, the ErrorException allows the file & line to be specified, any other Exception custom or not, doesn't allow you todo this, as all the getters on the Exception base class are maked final, so can't override.
    I think thats why this is in the ZE2 engine code, rather than in SPL.

  22. #22
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Ren
    A custom Exception wouldn't work the same, the ErrorException allows the file & line to be specified, any other Exception custom or not, doesn't allow you todo this, as all the getters on the Exception base class are maked final, so can't override.
    I think thats why this is in the ZE2 engine code, rather than in SPL.
    Yes, getLine is final, but it just returns $line, which is in turn protected, so it's ok to set it:

    PHP Code:
    class MyErr extends Exception
    {
        function 
    __construct($message ''$code 0$severity 0$file ''$line 0) {
            
    parent::__construct($message$code);
            
    $this->file $file;
            
    $this->line $line;
        }
    }

    set_error_handler(create_function('$no,$str,$file,$line',
        
    'throw new MyErr($str, 0, $no, $file, $line);'));

    try {
        
    $errline __LINE__ 1;
        
    fopen("blah");
    } catch(
    MyErr $e) {
        
    assert($e->getLine() == $errline);


  23. #23
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by sleepeasy
    error_reporting gets set to 0 (temporarily), and $severity is never 0, which is why your code works.
    Really? Interesting. Admittedly it's been a while since I coded that particular bit, but I still recall distinctly having to solve a problem with @ still generating errors. I'll have to check that when I get around to it.

  24. #24
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm not sure about that severity = 0, as I rely on @ in a part of my code.

    Anyway, I came with this pece of code which helps me mix and match things:

    PHP Code:
    function exceptions_error_handler($severity$message$filename$lineno)
    {
        
    $throwable  = array(E_ERROR,
                            
    //E_WARNING,
                            
    E_PARSE,
                            
    //E_NOTICE,
                            
    E_CORE_ERROR,
                            
    E_CORE_WARNING,
                            
    E_COMPILE_ERROR,
                            
    E_COMPILE_WARNING,
                            
    E_USER_ERROR,
                            
    E_USER_WARNING,
                            
    E_USER_NOTICE,
                            
    E_ALL,
                            
    //E_STRICT,
                            
    );
        
    //var_dump($severity);
        
    if (in_array($severity$throwable)) {
            throw new 
    ErrorException($message0$severity$filename$lineno);
        }


  25. #25
    SitePoint Zealot sleepeasy's Avatar
    Join Date
    Sep 2003
    Location
    Bristol, UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Ezku
    Really? Interesting. Admittedly it's been a while since I coded that particular bit, but I still recall distinctly having to solve a problem with @ still generating errors. I'll have to check that when I get around to it.
    The only place I've seen error_reporting getting set to 0 documented is here (the last sentence):

    Quote Originally Posted by http://php.net/set_error_handler
    It is important to remember that the standard PHP error handler is completely bypassed. error_reporting() settings will have no effect and your error handler will be called regardless - however you are still able to read the current value of error_reporting and act appropriately. Of particular note is that this value will be 0 if the statement that caused the error was prepended by the @ error-control operator.
    Always open to question or ridicule


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •