Php удаление объекта класса

Deleting entire PHP Class

Say that class exists in my code, then later on I no longer need this class and wish to remove it (so I can replace it with a new class later) Is it possible to delete an entire class from run time?

What does it mean? Do you want to replace your coding in the PHP file or want to reinitialize the class variable?

@Nish i think what he means is: when a class is defined it takes some space in memory (just the class itself, not its instances) so when he is done with the class, he wants to free the memory space taken by class definition.

Shaheer is close enough. I want to remove it from runtime so I can re-define it with a new class by the same name.

3 Answers 3

No, you cannot delete or substantially modify PHP classes (or functions) at runtime.

Use unset($classVariableName) to delete the instance and it will free the memory.

If the definition of the class shouldn’t be there at run-time, then the class needs to be added in separate file and the file should be included only when it is require. So that you can have two different class definition with same class name. But having two different definition with same name is not a good way to go.

Читайте также:  Java program with arraylist

You can use unset() to delete an object, but the class itself cannot be deleted. To be honest, modifying code like that at runtime sounds kludgy and confusing — is there not a better option?

Not many other options than reading the file, randomizing the class name then eval()ing the code. Kludgy— to you. It’s part of the architecture I have setup.

This question is in a collective: a subcommunity defined by tags with relevant content and experts.

Источник

How to delete a PHP object from its class?

I know that for some that might sound stupid, but I was thinking if I hava a delete() method in a class that removes all the object data (from DB and file system), how can I destroy/remove the object from within the class. This is a PHP question. Something like unset($this); Is it possible and wise? And what is the right way to do it?

I don’t understand the question. THe object itself lives in RAM and is deleted by the garbage collector as soon as there is no reference to it. If you take care of storing information about this object elsewhere, say in a database or a file, it is up to you to remove these data. There are many ways of storing data, and PHP cannot just guess the one you implemented.

I may have misunderstood — maybe you have the code to remove the data and you just do not know where to put it. In this case the method __destruct() will do.

So I can call __destrict in my delete() method, right? I do not want to wait for the GC or end of the script. I want to destroy/destruct the object right after I delete its data.

7 Answers 7

Whilst developing on a framework, I came across such issue as well. unset($this) is totally not possible, as $this is just a special pointer that allows you to access the current object’s properties and methods.

The only way is to encapsulate the use of objects in methods / functions so that when the method / function ends, the reference to the object is lost and garbage collector will automatically free the memory for other things.

See example RaiseFile , a class that represents a file:

In the RaiseFile class, it’ll be sensible that after you call the delete() method and the file is deleted, the RaiseFile object should also be deleted.

However because of the problem you mentioned, I actually have to insist that RaiseFile points to a file whether or not the file exists or not. Existence of the file can be tracked through the exists() method.

Say we have a cut-paste function that uses RaiseFile representation:

/** * Cut and paste a file from source to destination * @param string $file Pathname to source file * @param string $dest Pathname to destination file * @return RaiseFile The destination file */ function cutpaste($file, $dest)< $f = new RaiseFile($file); $d = new RaiseFile($dest); $f->copy($d); $f->delete(); return $d; > 

Notice how $f is removed and GC-ed after the function ends because there is no more references to the RaiseFile object $f outside the function.

Ok I see what you are doing here, but I was wondering if I can somehow destroy/GC a object from itself. Like self-destroying for objects 🙂

the answer is already clear, no an object cannot delete itself. I’m already providing the workaround for what you’re asking.

You cannot unset $this . Or more correctly: unset() on $this only has local effect on the variable. unset() removes the variable from the local scope, which reduces the ref count for the object. If the object is still referenced somewhere else, it will stay in memory and work.

Typically, the value of an ID property is used to determine if an object is stored in the back end. If the ID has a proper value, that object is stored. If the ID is null , it is not stored, yet. On successful storage you then set the ID accordingly. On delete you set the ID property to null again.

I’m building a CMS solution from the ground up and have a lot of references between objects; users, groups, categories, forums, topics, posts, etc.

I also use an «Object::getObject(id)» loader in each class which ensures there’s only one instance of an object per ID, but also means it’s even easier for code to pull a reference to existing objects.

When the data the object represents gets deleted from the data source, I’d like to wipe the object from memory and nullify all references to it to ensure other code doesn’t try to use an obsolete data set.

Ideally all references should be removed—the referencing code can provide a callback that gets fired at object deletion that can subsequently remove/update the reference. But if the referencing code gets sloppy, I’d rather it error out with a «Not an object» error than actually work with the object.

Without knowing how to force the destruction from within the object, itself, I’m being forced to:

  1. Begin almost every non-static method with a check to see if the object has been flagged «deleted», throwing an exception if it is. This ensures any referencing code can’t do any harm, but it’s a nasty thing to look at in the code.
  2. Unset every object variable after deletion from the database, so it doesn’t linger in memory. Not a big deal but, again: nasty to look at.

Neither would be needed if I could just destroy the object from within.

This depends on how you’ve structured your class.

If you’re following DTO/DAO patterns, your data would be separate from your model and you can simply remove the DTO. If you’re not, simply unsetting the data part of the class should do it.

But in actual terms, I think this is unnecessary since PHP will automatically cleanup at the end of the request. Unless you’re working on a giant object that takes up massive amounts of memory, and it’s a long process it’s not really worth the effort.

I think I am following them, but still at the end I want the object to self-destroy itself. I do not want to have a object which data was removed from DB and file system already.

It’s too difficult to give a correct answer without looking at your code. This entirely depends on how you’re storing your data and how your models and data are structured

well if memory is your biggest worry you could have an interface or a parent method deleteData() that would do some clean up on the data array. The model itself would be left untouched for you to carry out more operations.

There is a __destruct() magic method which is a destructor for a PHP Class.

Maybe you can put your deletion code in there and as soon as all reference to your objects are deleted, this destructor will be called and the data deleted.

Maybe I’m wrong, but the __destruct method is also called if the script is completed. Which means that after each request all your used objects will be automatically deleted from the database. Also see stackoverflow.com/questions/151660/…

Another approach is to make the delete-method static, which then could receive a PDO object and data, that determines what to delete. This way you don’t need to initialise the object.

Here is a sample solution which would be «reasonably usable» when implemented in well defined relationship/reference patterns, usually I drop something like this in my composites. To actually use the current code as I’ve done in this example in a real life would be going through too much trouble but it’s just to illustrate the how-to-point.

An object can’t just magically disappear — it will only be deleted (garbage collected) once there is nothing pointing at it. So «all» an object has to do is to keep track of everything that refers to it. It is fairly low friction when you have all the reference management built in — objects are created and passed on only by fixed methods.

Lets begin with a simple interface so we would be able to tell if it is safe to pass our reference to an object or not.

interface removableChildInterface

A class which can safely hold a reference to our object.

class MyParent implements removableChildInterface < public $children = array(); public function removeChild($child) < $key = array_search($child, $this->children); unset($this->children[$key]); > > 

And finally a class with the ability to self-destruct aka trigger the process of being removed by all of its parents.

class Suicidal < private $parents = array(); // Store all the reference holders private $id; // For example only private $memory = ''; // For example only public static $counter = 0; // For example only public function __construct(&$parent) < // Store a parent on creation $this->getReference($parent); // For the example lets assing an id $this->id = 'id_' . ++self::$counter; // and generate some weight for the object. for ($i = 0; $i < 100000; $i++) < $this->memory .= md5(mt_rand() . $i . self::$counter); > > // A method to use for passing the object around after its creation. public function getReference(&$parent) < if (!in_array($parent, $this->parents)) < $this->parents[] = &$parent; > return $this; > // Calling this method will start the removal of references to this object. // And yes - I am not actually going to call this method from within this // object in the example but the end result is the same. public function selfDestruct() < foreach ($this->parents as &$parent) < if (is_array($parent)) < $key = array_search($this, $parent); unset($parent[$key]); echo 'removing ' . $this->id . ' from an array
'; > elseif ($parent instanceof removableChildInterface) < $parent->removeChild($this); echo 'removing ' . $this->id . ' from an object
'; > // else throw your favourite exception > > // A final shout out right before being garbage collected. public function __destruct() < echo 'destroying ' . $this->id . '
'; > >

And for the example of usage, holding the reference in an array , in an object implementing our interface and the $GLOBALS array .

// Define collectors $array = array(); $parent = new MyParent(); // Store objects directly in array $array['c1'] = new Suicidal($array); $array['c2'] = new Suicidal($array); // Make a global reference and store in object $global_refrence = $array['c1']->getReference($GLOBALS); $parent->children[] = $array['c1']->getReference($parent); // Display some numbers and blow up an object. echo 'memory usage with 2 items ' . memory_get_usage() . ' bytes
'; $array['c1']->selfDestruct(); echo 'memory usage with 1 item ' . memory_get_usage() . ' bytes
'; // Second object is GC-d the natural way after this line echo '---- before eof ----' . '
';
memory usage with 2 items 6620672 bytes removing id_1 from an array removing id_1 from an array removing id_1 from an object destroying id_1 memory usage with 1 item 3419832 bytes ---- before eof ---- destroying id_2 

Источник

Как удалить объект, вызвав какой-либо его же собственный метод (PHP)?

Например, есть объект, который вызывает какую-то свою функцию (метод). Необходимо, чтобы после её вызова, объект стал null. Далее он записывается в базу, и если он null то ничего не записывается. Собственно мне нужно разрушить его собственной функцией, как это сделать?

P.S. я знаю, как это сделать с помощью return null или return $this. Но мне нужен метод типа void, который ничего не возвращает.

DmitriyEntelis

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

krocos

DmitriyEntelis

krocos

thestump

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

В объекте предусмотрите приватное свойство-флаг, который будет означать, что этот объект нехранимый.

me = $me; > public function forgetMe() < $this->persistent = false; // теперь нехранимый > /** * Какая то логика при сохранении */ public function save() < if (!$this->persistent) // если нехранимый < echo $this->me . " was NOT saved\n"; return true; // понять, простить и забыть > echo $this->me . " saved OK\n"; > > $obj1 = new Dummy('first'); $obj2 = new Dummy('second'); $obj1->forgetMe(); $obj1->save(); // -> first was NOT saved $obj2->save(); // -> second saved OK

Войдите, чтобы написать ответ

Можно ли получить список пользователей группы/чата с использование telegram API или telegram Bot API на php?

Источник

Оцените статью