Как уничтожить объект?

Насколько мне известно (чего очень мало), есть два способа:

$var = new object()

Потом:

// Method 1: Set to null
$var = null;
// Method 2: Unset 
unset($var); 

Другой лучший способ? Я тут волосы секу?


person PandemoniumSyndicate    schedule 10.01.2012    source источник


Ответы (6)


Вы ищете unset().

Но учтите, что нельзя явно уничтожить объект.

Он останется там, однако, если вы отключите объект и ваш скрипт подтолкнет PHP к ограничениям памяти, ненужные объекты будут собраны мусором. Я бы выбрал unset() (вместо того, чтобы устанавливать для него значение null), поскольку он, кажется, имеет лучшую производительность (не проверено, но задокументировано на один из комментариев из официального руководства PHP).

Тем не менее, имейте в виду, что PHP всегда уничтожает объекты, как только страница обслуживается. Так что это нужно только на очень длинных циклах и / или тяжелых страницах.

person Frankie    schedule 10.01.2012
comment
Итак, Фрэнки, я пришел из C ++, где, когда мы используем new один раз, мы должны использовать delete один раз. Это не так в PHP? Есть автоматическая сборка мусора, когда объект больше не нужен? - person gsamaras; 11.09.2015
comment
@gsamaras, это правда. Однако у вас также могут быть утечки, и вам следует прочитать больше о php GC, если вы используете демонов или что-то подобное. На большинстве сайтов запрос настолько недолговечный, что это не имеет значения. php.net/manual/en/features.gc.refcounting-basics. php - person Frankie; 11.09.2015
comment
unset() удаляет ссылку на объект? - person Yousha Aleayoub; 11.08.2017
comment
останется ли этот ответ в 2021 году? это необходимо для UnitTesting, концепция, которая, как я полагаю, не получила широкого распространения в 2012 году. - person clockw0rk; 04.05.2021

Удобный пост, объясняющий несколько неправильных представлений об этом:

Не вызывать деструктор явно

Это покрывает несколько заблуждений о том, как работает деструктор. Согласно документу PHP5, его явный вызов на самом деле не приведет к уничтожению вашей переменной:

PHP 5 представляет концепцию деструктора, аналогичную концепции других объектно-ориентированных языков, таких как C ++. Метод деструктора будет вызываться, как только не будет других ссылок на конкретный объект, или в любом порядке во время завершения работы.

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

person sturrockad    schedule 11.02.2014

Краткий ответ: необходимы оба.

Я чувствую, что был дан правильный ответ, но минимально. Да, обычно unset () лучше всего подходит для "скорости", но если вы хотите немедленно освободить память (за счет процессора), следует использовать null.

Как уже упоминалось, установка значения null не означает, что все будет восстановлено, у вас могут быть объекты с общей памятью (неклонированные), которые предотвратят разрушение объекта. Более того, как говорили другие, вы все равно не можете «уничтожить» объекты явно, так что вам все равно не следует пытаться это сделать.

Вам нужно будет выяснить, что лучше для вас. Также вы можете использовать __destruct () для объекта, который будет вызываться при unset или null, но его следует использовать осторожно и, как говорили другие, никогда не вызывать напрямую!

видеть:

http://www.stoimen.com/blog/2011/11/14/php-dont-call-the-destructor-explicitly/

В чем разница между присвоением NULL и отключением?

person Mike Q    schedule 18.04.2018

Это простое доказательство того, что вы не можете уничтожить объект, вы можете уничтожить только ссылку на него.

$var = (object)['a'=>1];
$var2 = $var;
$var2->a = 2;
unset($var2);
echo $var->a;

возвращается

2

Посмотрите, как это работает здесь: https://eval.in/1054130

person Yevgeniy Afanasyev    schedule 05.09.2018
comment
Да, вы уничтожили $var2, который был ссылкой на $var. Теперь вы также уничтожаете $var и, предполагая, что на объект нет других ссылок, все готово. - person i336_; 16.09.2018
comment
Вы не разрушаете объект, вы разрушаете указатель на объект. Это большая разница. - person Yevgeniy Afanasyev; 16.09.2018
comment
На других языках вы можете уничтожить объект, и все другие указатели выдадут вам исключения или мусор, но это не относится к php. - person Yevgeniy Afanasyev; 16.09.2018
comment
Вы не можете разрушить. Если нет ссылки, содержащей объект, объект готов к сбору сборщиком мусора. И вы не можете заставить запустить сборщик мусора. - person Daniel; 20.12.2019

Может быть в ситуации, когда вы создаете новый объект mysqli.

$MyConnection = new mysqli($hn, $un, $pw, $db);

но даже после того, как вы закроете объект

$MyConnection->close();

если вы будете использовать print_r() для проверки содержимого $MyConnection, вы получите сообщение об ошибке, как показано ниже:

Error:
mysqli Object

Warning: print_r(): Property access is not allowed yet in /path/to/program on line ..
( [affected_rows] => [client_info] => [client_version] =>.................)

в этом случае вы не можете использовать unlink(), потому что unlink() потребует строку имени пути, но в этом случае $MyConnection является объектом.

Итак, у вас есть другой выбор - установить для него значение null:

$MyConnection = null;

теперь все идет хорошо, как вы и ожидали. У вас нет содержимого внутри переменной $MyConnection, а также вы уже очистили объект mysqli.

Перед установкой значения переменной null рекомендуется закрыть объект.

person Subrat Kumar Palhar    schedule 26.10.2018

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

person hackartist    schedule 10.01.2012
comment
Если у вас действительно нет источников для резервного копирования ваших ответов, вам, вероятно, не стоит публиковать то, что, по вашему мнению, может произойти. Это бесполезно и приводит к тому, что подобная дезинформация принимается за правду и повторяется. - person meagar; 10.01.2012
comment
@meagar, это точная причина, по которой я связался с официальной страницей руководства, где в комментариях есть образец теста, сравнивающий unset () с null. - person Frankie; 10.01.2012