Edit report at https://bugs.php.net/bug.php?id=53648&edit=1
ID: 53648
Comment by: benjamin dot morel at strictcoding dot co dot uk
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:
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.
Previous Comments:
------------------------------------------------------------------------
[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