Как удалить все сылки на объект (PHP5)

Stur

Guest
Как удалить все сылки на объект (PHP5)

(PHP5)
Ситауция такая: создается новый объект класса Foo
PHP:
$arrFoo[]=new Foo();
Затем в процессе работы создается еще несколько ссылок на этот объект например так:
PHP:
$anyObject->Foo=$arrFoo[0];
$all[]=$arrFoo[0];
.....
мене надо создать такую функцию в классе Foo которая будет удалять объект вместе со всеми ссылками
чтобы можно было писать вот так
PHP:
$all[0]->destroy();
и объект удалялся бы начисто со всеми ссылками.

Есть ли в PHP5 встроенные функции которые позволяют по одной ссылке получить остальные, или удалить их?
 

tony2001

TeaM PHPClub
>мене надо создать такую функцию в классе Foo которая будет удалять объект вместе со всеми ссылками
лучше будет, если ты будешь описывать не требования, а задачу.
 

Константин_WEB

Guest
Re: Как удалить все сылки на объект (PHP5)

По-моему ты не создал здесь ни одной ссылки. Ты не использовал опереатор ссылки, а значит каждый раз ты копировал сам объект. Запомни, если хотя бы при одном присвоении ты не поставил &, то ты уже делаешь копию. Никакой функциональности по работе с "сылками" в PHP нет. Чтобы тебе было более понятно запомни, что под ссылкой подразумевается просто новое имя для существующей переменной, а не указатель или что-то подобное.

Поэтому, чтобы добится того, что ты хочешь, тебе нужно создать один экземпляр класса и использовать его посредством создания новых имён (ссылки). Возможное решение - это создание чего-то вроде фабрики классов. Создаёшь класс, у котор ты будешь запрашивать нужн объект, а он будет создавать и возвращать ссылку на него, если ты первый раз его запрашиваешь или просто возвращать ссылку на него, если это повторный запрос. Если ты в этом классе сделаешь unset такому объекту, то это и будет смерть обьекта и всех его ссылок (имён одного и того же объетка).
 

kvn

programmer
По-моему ты не создал здесь ни одной ссылки. Ты не использовал опереатор ссылки, а значит каждый раз ты копировал сам объект. Запомни, если хотя бы при одном присвоении ты не поставил &, то ты уже делаешь копию. Никакой функциональности по работе с "сылками" в PHP нет. Чтобы тебе было более понятно запомни, что под ссылкой подразумевается просто новое имя для существующей переменной, а не указатель или что-то подобное.
Уважаемый, наверное, не учел, что в названии темы присутствует PHP5...

2Stur

-> см. ответ Тони.
 

Stur

Guest
Я пытаюсь написать скрипт демона.
Демон будет запускатся из командной строки на сервере.
Программа клиент пишется на FlashMX.
Допустим класс Client будет инкапсулировать все все данные о поключенных клиентах.
Приходит новый клиент создается новый объект Client, и записывается я в глобальном массиве $pool
PHP:
if (($msg = socket_accept($MasterSock))) {
       $pool['вася'] = new clClient($msg);
    }
.............
//обрабатываем всех клиентов

foraech($pool as $key=>$value){
	$pool[$key]->run();
}
кроме того в зависимости от деиствий конкретного клиента он может быть зарегистрирован еще в нескольких процессах происходящих на сервере
PHP:
   $chat['вася']=$pool['вася'];
   $process1['вася']=$pool['вася'];
   $process2['вася']=$pool['вася'];
Затем клиент Вася разрывает соединение и идет спать. На сервере соответствующий объект класса Client обнаруживет, что связь разорванна и должен сам себя полностью удалить , чтобы освободить память.
В PHP, как известно, объект будет удален в том случае, если на него нет ни одной ссылки.
Вначале я пытался сделать так:
PHP:
class Client{
  var Name;	
	..........
  function run(){
	if(соединение разорванно){
		global $pool;
		unset($pool[$this->Name]);
		unset($this);
	
	}
   }

}
однако на этотт объект остаются ссылки в массивах $chat, $process1, $process2, и естественно он будет продолжать висеть в памяти.
Заранее неизвестно в каких процессах будет участвовать клиент, более того количество таких процессов на сервере также неизвестно, оно постоянно меняется. Т.е. количетво мест где товарищь Вася мог оставить ссылки на сомого cебя неизвестно.
Вот вам и задача: написать такой метод для класса Client что бы он начисто удалял все ссылки на самого себя (так чтобы произошел вызов __destruct() всамом объекте).
Думаю задача ясна.

Не хотелось бы все это делать програмным методом (реализовывать контроль ссылок в классе Client и т.д. )
Может быть есть какие-то внутренние функции в PHP5? Я ничего найти не смог :-(

PS Товарищам не ознакомившимся с Zend Engine2 просьба сюда не писать.
 

tony2001

TeaM PHPClub
>Я пытаюсь написать скрипт демона.
очень зря.

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

>PS Товарищам не ознакомившимся с Zend Engine2 просьба сюда не писать.
большая просьба такие "просьбы" более не писать.
 

fisher

накатила суть
>>Не хотелось бы все это делать програмным методом
>>(реализовывать контроль ссылок в классе Client и т.д. )
боюсь, это будет единственно правильным решением. правда неясно что пугает - это реализовать довольно просто, ну не будет присваивания $chat['вася']=$pool['вася'] будет вызов функции-метода-whatever, кода от этого сильно больше не станет. более того, реализация паттерна "observer" здесь даже логична: всем, кто "зарегистрировал" у себя удаляемый объект сначала отправляется уведомление о "дерегистрации".

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

GSL

Guest
А если просто для начала свести потери памяти к минимуму.

PHP:
class foo
{
    // очищает все внутренности объекта, 
    // делает его минимального  размера
    function Free(); 

    // метод проверки удаленности
   function isDeleted();
}
Далее по определенному событию запускаем чистильцика он быстро просматривает все списки и удаляет все isDeleted() = true;

Пример такого события можно организовать вызовом глобальной функции из метода Free() для подсчета количества удаленных объектов ждущих чистки, и если счетчки достик максимум то запускаем чистильцика...

Примечание !!! Free вызвается только 1 раз для каждого объекта он должен освободить всю память внутри объекта.

Если передовались только ссылки на объекты будет работать :)
 

Screjet

Новичок
Заранее неизвестно в каких процессах будет участвовать клиент, более того количество таких процессов на сервере также неизвестно, оно постоянно меняется. Т.е. количетво мест где товарищь Вася мог оставить ссылки на сомого cебя неизвестно.
Любопытно, как такое может быть: программе известно в каких процессах будет участвовать клиент, а программисту = неизвестно :)

Для начинающих ПХП5 кодеров, если есть два варианта ПХП(4 и 5):
PHP:
class hello {                            
    function hello( $name ){             
        $this->name = $name;             
        echo "Hello ".$this->name."\n";  
    }                                    
    function bye(){                      
        echo "Bye ".$this->name."\n";    
    }                                    
    function __destruct(){               
        $this->bye();                    
    }                                    
}                                        
                                         
$hello = new hello('Vasya');             
$a = $hello;                             
$a->name = 'Petya';                      
$hello->bye();                           
echo "Done\n";
 

Stur

Guest
Любопытно, как такое может быть: программе известно в каких процессах будет участвовать клиент, а программисту = неизвестно
например если мы имеем многокомнатный чат каждая комната отдельный процесс то заранее неизвестно где может зарегистрироватся клиент
Уважаемый Screjet не пойму в чем смысл вышего примера?
Я после нескольких неудачных проб поше по такому пути. Создал один ассоциативный массив $pool прописывается новый клиент
$pool[$SID]=new clClient();
а затем этот $SID служит для регистрации клиента в любых процессах
можно всегда проверить есть объект или нет
if (isset($pool[$SID]){........}
а если надо удалить то дастаточно
unset($pool[$SID]);
есть и недостатки в процессах могут остататся $SID
и может произойти вызов без предварительной проверки на существования данного клиента ну например $pool[$SID]->send("Hello");
а $pool[$SID] уже удален то такая команда вызовет фатальную ошибку.
:confused:
 

Screjet

Новичок
Originally posted by Stur
например если мы имеем многокомнатный чат каждая комната отдельный процесс то заранее неизвестно где может зарегистрироватся клиент

Даже если комнаты создаются и уничтожаются онлайн, то известено, что посетитель будет в комнатах, каких = неважно.
"Процесс" = подразумевается отдельный процесс ОС или какой либо внутренний процесс ПХП скрипта (чисто условно)?
Уважаемый Screjet не пойму в чем смысл вышего примера?
Смысл в том, чтоб показать новичкам отличие ПХП4 от ПХП5. Специалисту не обязательно выполнять столь простой скрипт, чтоб увидеть результат.
Я после нескольких неудачных проб поше по такому пути. Создал один ассоциативный массив $pool прописывается новый клиент
$pool[$SID]=new clClient();
а затем этот $SID служит для регистрации клиента в любых процессах
можно всегда проверить есть объект или нет
if (isset($pool[$SID]){........}
а если надо удалить то дастаточно
unset($pool[$SID]);
есть и недостатки в процессах могут остататся $SID
и может произойти вызов без предварительной проверки на существования данного клиента ну например $pool[$SID]->send("Hello");
а $pool[$SID] уже удален то такая команда вызовет фатальную ошибку.
:confused:
Вопросов нет. Все верно, так и нужно делать: открывать массивы(хеши) для незвестных заранее элементов.
 
Сверху