Php Не Любит Деструкторы

Столько воды утекло с тех пор, как PHP объявил себя языком ООП.

Я не смог уточнить, когда именно, но «13 июля 2004 года был выпущен PHP 5, работающий на новом Zend Engine II. PHP 5 включает новые функции, такие как улучшенная поддержка объектно-ориентированного программирования».

То есть теоретически конструкторы и деструкторы уже тогда появились.

Я сам использую версию 5.3.2, но поражен тем, на что она способна.

Немного о себе.

Я программист C++ с 4-летним опытом.

Специализация: компьютерная графика и сети.

А именно создание онлайн-игр.

Но таким играм нужен сервер, а серверу нужна база игроков.

И игрокам тоже нужен сайт. «Зачем нанимать веб-программиста, я и сам неплохой.

В то же время я выучу язык».

Я так думала пол года назад, но до сих пор не могу понять!



Классический
Думаю, многие, кто работал с деструкторами, когда-то сталкивались: Неустранимая ошибка PHP: исключение выдается без кадра стека в неизвестном месте в строке 0 Первая реакция – недоумение.

Второй матовый.

А нажатие повсюду exit() не дает результатов, потому что догадываюсь, что исключение в деструкторе приходит не сразу, а если оно и происходит, то, скорее всего, кодовая база значима.

Ответ в bugs.php.net/bug.phpЭid=33598

[email protected]: Throwing exceptions in __desctruct() is not allowed. Should be documented. [email protected]: Thank you for the report, and for helping us make our documentation better. "Attempting to throw an exception from a desctructor causes a fatal error."

Забавный? Лично мне это не очень нравится.

Воспроизвести ошибку с неявным исключением очень просто.



class a { // .

public function __destruct() { global $_SESSION; $_SESSION = "Some information"; } } $dummy = new a();

^Обратите внимание, явные исключения иногда работают правильно.

Я поэкспериментирую, чтобы посмотреть, какой эффект это даст.

Обратный порядок очистки
Давайте иметь следующий код в некоторой области (глобальной и не очень):

$earth = new world(); $vasya = new human($earth);

Соответственно, в коде конструктора человека происходит его контакт с миром.

(Предполагается, что без мира Васи не будет, давайте отбросим философию, надо быстро закрывать проект.) Ну а в коде деструктора Васи лежит аля $this-> my_world-> RemoveHumanFromWorld($this), в котором вызываются RemoveAllMyStuff, CalculateKarma и так далее.

(Предположим, что связи с Васей у нас в мире нет, так как в рамках задачи этого не требовалось) Что делает PHP, когда выходит за рамки? Уничтожает мир и вылетает с ошибкой «Неустранимая ошибка: вызов функции-члена RemoveHumanFromWorld() для необъекта в /home/god/my_projects/earth/creatures/reasonable/homo_sapiens.php в строке 1956».

(Поэтому, кстати, мир был написан на C++, потому что Богу не нужно, чтобы он работал в какой-либо вселенной.

Виртуальное пространство со сборщиком мусора.

Ха-ха.

) Ответить с помощью bugs.php.net/bug.phpЭid=36759 [email protected] Исправлено в CVS HEAD и PHP_5_2. Вот бы найти этого Дмитрия и ткнуть его носом, как на той картинке.

Не знаю как в последних версиях, еще не обновлялся, но в 5.3 актуально.



Завершение сценария является исключением
Ох, как много можно об этом написать.

Глобальные переменные (аля сессии) перестают быть действительными, доступ к файловой системе отсекается.

И вообще, насколько я понимаю, корректная работа скрипта не гарантируется.

Так что не дай бог вам что-то сделать в деструкторе глобального объекта.

Но давайте оставим это.

В документации PHP 5.1 и ранее (не могу найти строфу и стих) написано: «Метод деструктора будет вызван, как только не будет других ссылок на тот или иной объект», что в принципе логично для языке без строгого требования к конструкции удаления (лат. unset).

После отчета об ошибке bugs.php.net/bug.phpЭid=38572 Документация изменилась: «Метод деструктора будет вызван, как только не будет других ссылок на конкретный объект или в любом порядке во время последовательности завершения работы» Комфортный? Для меня - не очень.



Только прямые ссылки
Пусть по логике языка объект $a должен быть удален раньше $b. Но пусть объект $b хранит ссылку на поле $a-> some_data. Тогда по логике объект $b должен быть удален раньше.

Увы, в PHP это не так.

Такого бага я не нашел, но ситуация специфическая (и смею сказать исключительная).

Этого можно избежать слабым патчем до ссылки на $a, это терпимо и я об этом не сообщал.



Тупик в стиле PHP
$а-> ref = $b; $b-> ref = $а; Одно время меня интересовало, как PHP справится с перекрестными ссылками.

Оно замерзнет? Появится ли у вас ошибка «вы не можете покинуть область действия» и как это будет звучать по-английски? Увы, теплица показала, что все переменные будут существовать до конца, пока не наступит, как говорится, «или в любом порядке во время последовательности выключения» Заключение На данный момент это все, что я помню.

Или, может быть, все, с чем я столкнулся.

Но у меня сложилось впечатление, что деструкторы в PHP — это костыль, так что, скорее всего, скоро я снова с этим столкнусь.

Мне кажется, будущее ООП веб-программирования за интерпретатором C++, и, возможно, оно будет готово.

Возможно, кто-то однажды решит изменить C++, добавить стандартные конструкции, чтобы он стал веб-ориентированным.

Но пока альтернативы я не нашел.

Ссылки ru.wikipedia.org/wiki/PHP php.net/manual/en/language.oop5.decon.php Хотя в этом нет ничего тривиального: [ http://].

*php\.

net.* Теги: #php #php5 #Деструкторы #bugs #bugs #php

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.