Edit report at https://bugs.php.net/bug.php?id=53648&edit=1
ID: 53648 Comment by: dqhendricks at hotmail dot com 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: 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; Previous Comments: ------------------------------------------------------------------------ [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