<?php
set_error_handler(array('My_ToStringFixer', 'errorHandler'));
error_reporting(E_ALL | E_STRICT);
class My_ToStringFixer
{
protected static $_toStringException;
public static function errorHandler($errorNumber, $errorMessage, $errorFile, $errorLine)
{
if (isset(self::$_toStringException))
{
$exception = self::$_toStringException;
// Always unset '_toStringException', we don't want a straggler to be found later if something came between the setting and the error
self::$_toStringException = null;
if (preg_match('~^Method .*::__toString\(\) must return a string value$~', $errorMessage))
throw $exception;
}
return false;
}
public static function throwToStringException($exception)
{
// Should not occur with prescribed usage, but in case of recursion: clean out exception, return a valid string, and weep
if (isset(self::$_toStringException))
{
self::$_toStringException = null;
return '';
}
self::$_toStringException = $exception;
return null;
}
}
class My_Class
{
public function doComplexStuff()
{
throw new Exception('Oh noes!');
}
public function __toString()
{
try
{
// do your complex thing which might trigger an exception
return $this->doComplexStuff();
}
catch (Exception $e)
{
// The 'return' is required to trigger the trick
return My_ToStringFixer::throwToStringException($e);
}
}
}
$x = new My_Class();
try
{
echo $x;
}
catch (Exception $e)
{
echo 'Caught Exception! : '. $e;
}
Fatal error: Uncaught TypeError: My_Class::__toString(): Return value must be of type string, null returned in /in/DI9em:54
Stack trace:
#0 /in/DI9em(63): My_Class->__toString()
#1 {main}
thrown in /in/DI9em on line 54
Process exited with code 255.
Output for 7.4.0 - 7.4.33
Fatal error: Uncaught Error: Method My_Class::__toString() must return a string value in /in/DI9em:63
Stack trace:
#0 {main}
thrown in /in/DI9em on line 63
Process exited with code 255.
Fatal error: Method My_Class::__toString() must return a string value in /in/DI9em on line 63
Process exited with code 255.
Output for 4.4.2 - 4.4.9
Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /in/DI9em on line 7
Process exited with code 255.
Parse error: parse error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /in/DI9em on line 7
Process exited with code 255.
Output for 4.3.2 - 4.3.4
Parse error: parse error, expecting `T_OLD_FUNCTION' or `T_FUNCTION' or `T_VAR' or `'}'' in /in/DI9em on line 7
Process exited with code 255.