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

120

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

$var = new object()

Затем:

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

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

PandemoniumSyndicate
источник

Ответы:

152

Вы ищите unset().

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

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

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

Фрэнки
источник
1
Итак, Фрэнки, я пришел из C ++, где, когда мы используем newодин раз, мы должны использовать deleteодин раз. Это не так в PHP? Есть автоматическая сборка мусора, когда объект больше не нужен?
gsamaras
3
@gsamaras, это правда. Однако у вас также могут быть утечки, и вам следует прочитать больше о php GC, если вы используете демонов или что-то подобное. На большинстве сайтов запрос настолько недолговечный, что не имеет значения. php.net/manual/en/features.gc.refcounting-basics.php
Фрэнки
unset()Удаляет ли ссылку на объект?
Юша Алеайуб
9

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

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

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

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

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

sturrockad
источник
2

Краткий ответ: нужны оба.

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

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

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

видеть:

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

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

Майк Кью
источник
0

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

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

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

2

Посмотреть в действии можно здесь: https://eval.in/1054130

Евгений Афанасьев
источник
3
Да, вы уничтожили, на $var2что была ссылка $var. Теперь вы также уничтожаете $varи, предполагая, что на объект нет других ссылок, все готово.
i336_
4
Вы не разрушаете объект, вы разрушаете указатель на объект. Это большая разница.
Евгений Афанасьев
1
На других языках вы можете уничтожить объект, и все остальные указатели выдадут вам исключения или мусор, но это не относится к php
Евгений Афанасьев
1
Вы не можете разрушить. Если нет ссылки, содержащей объект, объект готов к сборке сборщиком мусора. И вы не можете заставить запустить сборщик мусора.
Даниэль
0

Может быть в ситуации, когда вы создаете новый объект 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.

Субрат Кумар Палхар
источник
-7

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

hackartist
источник
16
Если у вас действительно нет источников для резервного копирования ваших ответов, вам, вероятно, не следует публиковать то, что, по вашему мнению, «может» произойти. Это бесполезно и приводит к тому, что подобная дезинформация принимается за правду и повторяется.
meagar
1
@meagar, это точная причина, по которой я связался с официальной страницей руководства, где в комментариях есть образец теста, сравнивающий unset () с null.
Фрэнки