Как выкинуть исключение в __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 и за пару-тройку запусков роняет его вовсе.

Тэги: , ,

Комментарии

#1 dkrnl 20.03.10, 10:43

Чтобы не мучатся с отладкой toString мы делаем примерно так:


public function __toString()
...
{
try
{
$this->render();
}
catch(Exception $e)
{
Aquilon_Catcher::throwException($e);
}
}
...
public function throwException(Exception $e)
{
...
echo $e;
exit;
}
...

#2 Sam 20.03.10, 12:44

Меня подобный подход не спас — апачу всё так же плохело. Не отлавливается ли исключение или происходит что-то иное пока не выяснял.

#3 AmdY 20.03.10, 14:40

Из __toString вообще пока нельзя выбрасывать исключения. И метод вовсе не предполагалось использовать в методах типа explode, только для echo, print :( http://www.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.tostring

Оставить комментарий




Подписаться на RSS

Интересное

Разделы

  1. (5)
  2. (11)
  3. (6)
  4. (9)
  5. (6)
  6. (6)
  7. (16)
  8. (60)
  9. (274)
  10. (52)
  11. (16)
  12. (12)
  13. (37)
  14. (6)
  15. (10)
  16. (14)
  17. (18)
  18. (16)
  19. (7)
  20. (8)
  21. (7)
  22. (7)
  23. (31)
  24. (76)
  25. (27)
  26. (68)
  27. (5)
  28. (203)
  29. (59)
  30. (6)
  31. (19)
  32. (73)
  33. (27)
  34. (70)
  35. (33)
  36. (10)
  37. (5)
  38. (6)
  39. (5)
  40. (341)
  41. (14)
  42. (11)
  43. (6)
  44. (13)
  45. (8)
  46. (18)
  47. (6)
  48. (15)
  49. (115)
  50. (18)
  51. (6)
  52. (9)
  53. (71)
  54. (16)
  55. (6)
  56. (25)
  57. (13)
  58. (5)
  59. (39)
  60. (7)
  61. (31)
  62. (7)
  63. (12)
  64. (11)
  65. (124)
  66. (34)
  67. (5)
  68. (18)
  69. (28)
  70. (9)
  71. (6)
  72. (8)
  73. (41)
  74. (10)
  75. (6)
  76. (12)
  77. (5)
  78. (9)
  79. (6)

Друзья