Как выкинуть исключение в __toString и к чему это приведёт
20 марта 2010
Как известно, исключения кидать в __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 и за пару-тройку запусков роняет его вовсе.
Комментарии RSS по email OK
Чтобы не мучатся с отладкой toString мы делаем примерно так:
public function __toString()
...
{
try
{
}
catch(Exception $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