В каком порядке объекты уничтожаются в PHP?

каков точный порядок деконструкции объекта?

из тестирования у меня есть идея: FIFO для текущей области.

class test1
{
    public function __destruct()
    {
        echo "test1n";
    }
}

class test2
{
    public function __destruct()
    {
        echo "test2n";
    }
}

$a = new test1();
$b = new test2();

который производит одни и те же результаты снова и снова:

test1
test2

на руководство по PHP расплывчато (акцент мой, чтобы подчеркнуть неопределенность): "метод деструктора будет вызван, как только не будет других ссылок на конкретный объект,или в любом порядке во время остановки последовательность."

каков точный порядок деконструкции? Может ли кто-нибудь подробно описать реализацию порядка уничтожения, который использует PHP? И если этот порядок не согласуется между любыми версиями PHP, может ли кто-нибудь точно определить, в каких версиях PHP этот порядок изменяется?

2 ответов


прежде всего, здесь рассматривается немного об общем порядке уничтожения объекта:https://stackoverflow.com/a/8565887/385378

в этом ответе я буду заниматься только тем, что происходит, когда объекты все еще живы во время завершения запроса, т. е. если они ранее не были уничтожены через механизм пересчета или круговой сборщик мусора.

завершение запроса PHP обрабатывается в php_request_shutdown


каков точный порядок деконструкции? Может ли кто-нибудь подробно описать реализацию порядка уничтожения, который использует PHP? И если этот порядок не согласуется между любыми версиями PHP, может ли кто-нибудь точно определить, в каких версиях PHP этот порядок изменяется?

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

точный порядок уничтожения не всегда ясен, но всегда согласован с учетом одного скрипта и PHP версия. То есть тот же скрипт, работающий с теми же параметрами, который создает объекты в том же порядке, в основном всегда будет получать тот же порядок уничтожения, пока он работает на той же версии PHP.

процесс выключения -- вещь, которая запускает уничтожение объекта, когда выполнение скрипта остановлено -- и изменилось в недавнем прошлом, по крайней мере, дважды, что косвенно повлияло на порядок уничтожения. Один из этих двух ошибок в какой-то старый код, который я пришлось поддерживать.

большой вернулся в 5.1. До 5.1 сеанс пользователя записывался на диск в самом начале последовательности завершения работы, перед уничтожением объекта. Это означало, что обработчики сеансов могли получить доступ ко всему, что оставалось над объектами, например, к настраиваемым объектам доступа к базе данных. В 5.1, сессии были написаны после одна развертка разрушения объекта. Чтобы сохранить предыдущее поведение, необходимо вручную зарегистрировать функцию завершения работы (которые запускаются в порядке определения в начале shutdown до destruction) для успешной записи данных сеанса, если подпрограммам записи нужен (глобальный) объект.

неясно, было ли изменение 5.1 предназначено или было ошибкой. Я видел оба заявления.

следующее изменение было в 5.3, с введением новая система сбора мусора. В то время как порядок операций при выключении оставался прежним, точный порядок уничтожения теперь может измениться на основе подсчета ссылок и других восхитительных ужасов.

NikiC это!--22--> сведения о настоящее (на момент написания) внутренняя реализация процесса выключения.

еще раз, это не гарантируется нигде, и документация очень четко говорит вам никогда не предполагать порядок уничтожения.