Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Вызов деструктора в PHP 5  (Прочитано 12160 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Алик
Постоялец

kz
Offline Offline

« : 12-09-2011 15:29 » 

Добрый день!

Интересует точный момент вызова деструктора объекта в PHP. кто знает точно, вызовется ли он гарантированно в том месте, где на объект исчезает последняя ссылка (например, перед выходом из функции, где он был создан); либо же деструктор будет вызван, когда у сборщика мусора руки дойдут удалить этот объект?
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 12-09-2011 16:15 » 

http://ru2.php.net/manual/en/language.oop5.decon.php

Цитата
The destructor method will be called as soon as all references to a particular object are removed or when the object is explicitly destroyed or in any order in shutdown sequence.

Проверяется элементарным тестом:

Код: (PHP) t1.php
<?php

class A
{
    public function __destruct()
    {
        echo "Destructor\n";
    }
}

function func1()
{
    $a = new A();
}

$a = new A();
echo "Test point 1\n";
unset($a);
echo "Test point 2\n";
func1();
echo "Test point 3\n";

$ php t1.php
Test point 1
Destructor
Test point 2
Destructor
Test point 3

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

Цитата
Like constructors, parent destructors will not be called implicitly by the engine. In order to run a parent destructor, one would have to explicitly call parent::__destruct() in the destructor body.
« Последнее редактирование: 12-09-2011 16:20 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алик
Постоялец

kz
Offline Offline

« Ответ #2 : 13-09-2011 04:31 » 

Да, тест хороший. Но где гарантия, что деструкторы ВСЕГДА будут вызываться в этой последовательности? Наприме, в Java если я не ошибаюсь, прямо сказано, что деструктор будет вызван тогда, когда сборщику мусором взбредет в голову уничтожить объект.
Написано ли где-то в  документации PHP, что деструктор вызывается СРАЗУ?

Добавлено через 3 минуты и 1 секунду:
а, ну да, вроде, написано :
Цитата
The destructor method will be called as soon as all references to a particular object are removed or when the object is explicitly destroyed or in any order in shutdown sequence
« Последнее редактирование: 13-09-2011 04:34 от Алик » Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 13-09-2011 06:45 » 

Давай проверим с циклическими ссылками.

Код: (PHP) t2.php
class A
{
    public $b;

    public function __construct()
    {
        $this->b = new B($this);
    }

    public function __destruct()
    {
        echo "Destructor A\n";
    }
}

class B
{
    public $a;

    public function __construct($a)
    {
        $this->a = $a;
    }

    public function __destruct()
    {
        echo "Destructor B\n";
    }
}

$t = 1;
$a = new A();
echo "Test point ", $t++, "\n";
unset($a);
echo "Test point ", $t++, "\n";

$ php t2.php
Test point 1
Test point 2
Destructor A
Destructor B

Циклические ссылки не позволяют уничтожить объект сразу...

Сделаем принудительно:

Код: (PHP) t3.php
class A
{
    public $b;

    public function __construct()
    {
        $this->b = new B($this);
    }

    public function __destruct()
    {
        echo "Destructor A\n";
    }

    public function cleanup()
    {
        unset($this->b);
    }
}

class B
{
    public $a;

    public function __construct($a)
    {
        $this->a = $a;
    }

    public function __destruct()
    {
        echo "Destructor B\n";
    }
}

$t = 1;
$a = new A();
echo "Test point ", $t++, "\n";
$a->cleanup();
echo "Test point ", $t++, "\n";
unset($a);
echo "Test point ", $t++, "\n";

$ php t3.php
Test point 1
Destructor B
Test point 2
Destructor A
Test point 3

Очистка гарантирована.
« Последнее редактирование: 13-09-2011 06:53 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines