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