Bug #67509 [Nab]: set_error_handler ignores class scope

From: Date: Wed, 25 Jun 2014 09:55:53 +0000
Subject: Bug #67509 [Nab]: set_error_handler ignores class scope
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-186336@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=67509&edit=1

 ID:                 67509
 User updated by:    tugrultopuz at gmail dot com
 Reported by:        tugrultopuz at gmail dot com
 Summary:            set_error_handler ignores class scope
 Status:             Not a bug
 Type:               Bug
 Package:            Scripting Engine problem
 Operating System:   Debian 7.2
 PHP Version:        5.4.29
 Block user comment: N
 Private report:     N

 New Comment:

OK. I understood. Class scope should be on calling time instead of registering time.

Yes I can make the way that your solution. Going to be a little dirty.

It works like following

<?php

namespace My;

class Exception extends \Exception
{
    protected $context;
    
    public static function setErrorHandler()
    {
        set_error_handler('static::_errorHandler');
    }
    
    public static function restoreErrorHandler()
    {
        return restore_error_handler();
    }
    
    protected static function _errorHandler($number, $message, $file, $line, $context)
    {
        self::restoreErrorHandler();

        $exception = new static($message, $number);
        $exception->file = $file;
        $exception->line = $line;
        $exception->context = $context;

        throw $exception;
    }
    
    public static function triggerError($message)
    {
        trigger_error($message);
    }
}

\My\Exception::setErrorHandler();

try {
    \My\Exception::triggerError('My custom error!');
} catch (\My\Exception $ex) {
    echo $ex->getMessage();
}



\My\Exception::restoreErrorHandler();


Previous Comments:
------------------------------------------------------------------------
[2014-06-25 01:23:16] requinix@php.net

The error handler isn't executing until the error happens and that's long after scope has
left the setErrorHandler() method. It cannot know what you meant by "static".

Specify the class name.

  set_error_handler(__CLASS__ . '::_errorHandler'); // or get_called_class()

Then you'll get an error about being unable to call a protected method, which you can resolve
by making _errorHandler() public.

------------------------------------------------------------------------
[2014-06-25 00:20:33] tugrultopuz at gmail dot com

Description:
------------
I tried to send static method of a class as the callback. 

Test script:
---------------
<?php

namespace My;

class Exception extends \Exception
{
    protected $context;
    
    public static function setErrorHandler()
    {
        set_error_handler('static::_errorHandler');
    }
    
    public static function restoreErrorHandler()
    {
        return restore_error_handler();
    }
    
    protected static function _errorHandler($number, $message, $file, $line, $context)
    {
        self::restoreErrorHandler();

        $exception = new static($message, $number);
        $exception->file = $file;
        $exception->line = $line;
        $exception->context = $context;

        throw $exception;
    }
}

\My\Exception::setErrorHandler();

try {
    trigger_error('My custom error!');
} catch (\My\Exception $ex) {
    echo 'Error Message:', $ex->getMessage();
}

\My\Exception::restoreErrorHandler();



Expected result:
----------------
Error Message: My custom error!

Actual result:
--------------
Warning: Invalid callback static::_errorHandler, cannot access static:: when no class scope is
active in test.php on line 17


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=67509&edit=1


Thread (3 messages)

« previous php.bugs (#186336) next »