Как выкинуть исключение в __toString и к чему это приведёт
Как известно, исключения кидать в __toString() PHP запрещает. Выглядит это не очень-то логично, но запрещено не просто так. Вообще __toString() — штука крайне нестабильная и сложная в отладке.
Оказалось, что исключение в __toString() выкинуть всё-таки можно при помощи своего обработчика ошибок и приведёт это довольно неожиданным результатам.
Вот такой код
class X {
function __toString(){
$this->test();
}
function test(){
explode(',', new self);
}
}
echo new X();
выдаст нам вполне понятный «Catchable fatal error: Object of class X could not be converted to string». Добавим свой обработчик ошибок, конвертирующий их в исключения.
Генерация исключений вместо ошибок популярна из за возможности получить стек вызовов и другую полезную отладочную информацию и используются в большом количестве фреймворков. Например, в Yii.
set_error_handler('handle_error');
function handle_error($errno, $errstr, $errfile, $errline, $errcontext){
throw new Exception('test');
}
Выполнение, проходившее ранее более-менее корректно, теперь вызывает мощное размножение процессов и тредов Apache и за пару-тройку запусков роняет его вовсе.
Комментарии
Чтобы не мучатся с отладкой toString мы делаем примерно так:
public function __toString()
...
{
try
{
$this->render();
}
catch(Exception $e)
{
Aquilon_Catcher::throwException($e);
}
}
...
public function throwException(Exception $e)
{
...
echo $e;
exit;
}
...
Меня подобный подход не спас — апачу всё так же плохело. Не отлавливается ли исключение или происходит что-то иное пока не выяснял.
Из __toString вообще пока нельзя выбрасывать исключения. И метод вовсе не предполагалось использовать в методах типа explode, только для echo, print :( http://www.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.tostring
Оставить комментарий