Edit report at https://bugs.php.net/bug.php?id=53648&edit=1
ID: 53648 Comment by: ni...@php.net Reported by: clicky at erebot dot net Summary: Allow __toString() to throw exceptions Status: Open Type: Feature/Change Request Package: Class/Object related PHP Version: 5.3.4 Block user comment: N Private report: N New Comment: @benjamin: I don't think anyone opposes this feature request, it's just too hard to implement. Allowing __toString to throw exceptions would require any internal code doing a zval to string conversion to be exception-safe. See also: http://markmail.org/message/lkpmpnhrvcbafhkd Previous Comments: ------------------------------------------------------------------------ [2012-12-04 12:57:36] benjamin dot morel at strictcoding dot co dot uk I strongly support this feature request. I haven't read any valid supportive argument so far, for keeping this behaviour as it is currently. In case someone would be worried about backward compatibility issues, this change could be introduced with the next major version, PHP 5.5! I would be grateful if a member of the PHP team could review this request. ------------------------------------------------------------------------ [2011-11-10 04:05:48] dqhendricks at hotmail dot com this problem is causing me such a headache. i'm not even trying to convert an object to a string and i'm getting this error. the bug become such a pain to track. i have an active record that lazy loads child objects through __get. so even though im just trying to print a property of an object that is a string, the fact that a __get is used to get that object, prevents me from throwing exceptions. it looks like this echo $activerecord->childobject->somestring; ------------------------------------------------------------------------ [2011-01-04 14:45:29] clicky at erebot dot net Description: ------------ Currently, when casting an object with __toString() to a string, __toString() is not allowed to throw an exception. Trying to do so triggers an E_ERROR "Method %s::__toString() must not throw an exception". IMHO, this is counter-intuitive, especially since calling that object's __toString() method directly would correctly throw the exception. I propose to allow __toString() to throw exceptions. Note: this was already reported in http://bugs.php.net/bug.php?id=50699 but marked as bogus with the only explanation being "__toString must not throw". So, I'm marking this as a feature request rather than a bug, since the current behaviour seems to be expected (though it is not documented in http://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.tostring). I also found this entry http://stackoverflow.com/questions/2429642/why-its-impossible-to-throw-exception-from-tostring which cites Johannes saying this requires major changes in the code. However, the article mentioned is from 2007 and I think the limitations in ZE that prevented this to be implemented were lifted since then. I'm not very versed in PHP's inner workings, but attached is a tentative patch which seems to fix this issue. Test script: --------------- <?php class CustomException extends Exception { } class Foo { public function __toString() { throw new CustomException('oops!'); } } $foo = new Foo(); try { var_dump((string) $foo); } catch (CustomException $e) { var_dump($e); } ?> Expected result: ---------------- object(CustomException)#2 (7) { ["message":protected]=> string(5) "oops!" ["string":"Exception":private]=> string(0) "" ["code":protected]=> int(0) ["file":protected]=> string(17) "/tmp/toString.php" ["line":protected]=> int(65) ["trace":"Exception":private]=> array(1) { [0]=> array(6) { ["file"]=> string(17) "/tmp/toString.php" ["line"]=> int(71) ["function"]=> string(10) "__toString" ["class"]=> string(3) "Foo" ["type"]=> string(2) "->" ["args"]=> array(0) { } } } ["previous":"Exception":private]=> NULL } Actual result: -------------- PHP Fatal error: Method Foo::__toString() must not throw an exception in /tmp/toString.php on line 0 PHP Stack trace: PHP 1. {main}() /tmp/toString.php:0 ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=53648&edit=1