Why it's impossible to throw exception from __toString()?

后端 未结 6 1885
半阙折子戏
半阙折子戏 2020-12-29 18:33

Why it\'s impossible to throw exception from __toString()?

class a
{
    public function __toString()
    {
        throw new Exception();
    }
}

$a = new          


        
6条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-12-29 18:41

    in response to the accepted answer, I came up with a (perhaps) better way to handle exceptions inside __toString():

    public function __toString()
    {
        try {
            // ... do some stuff
            // and try to return a string
            $string = $this->doSomeStuff();
            if (!is_string($string)) {
                // we must throw an exception manually here because if $value
                // is not a string, PHP will trigger an error right after the
                // return statement, thus escaping our try/catch.
                throw new \LogicException(__CLASS__ . "__toString() must return a string");
            }
    
            return $string;
        } catch (\Exception $exception) {
            $previousHandler = set_exception_handler(function (){
            });
            restore_error_handler();
            call_user_func($previousHandler, $exception);
            die;
        }
    }
    

    This assumes there is an exception handler defined, which is the case for most frameworks. As with the trigger_error method, doing this will defy the purpose of try..catch, but still it is much better than dumping output with echo. Also, many framework transform errors into exceptions, so trigger_error won't work anyway.

    As an added bonus, you'll get a full stack-trace as with normal exceptions and the normal dev-production behaviour of your framework of choice.

    Works very well in Laravel, and I'm pretty sure it'll work in pretty much all the modern PHP frameworks out there.

    Screenshot relevant:
    note: in this example, output() is called by a __toString() method.

    __toString() exception caught by Laravel exception handler

提交回复
热议问题