Wie zerstöre ich ein Objekt?

120

Soweit ich weiß (was sehr wenig ist), gibt es zwei Möglichkeiten:

$var = new object()

Dann:

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

Andere bessere Methode? Spalte ich hier Haare?

PandemoniumSyndicate
quelle

Antworten:

152

Du suchst unset().

Beachten Sie jedoch, dass Sie ein Objekt nicht explizit zerstören können.

Es bleibt dort, aber wenn Sie das Objekt deaktivieren und Ihr Skript PHP an die Speichergrenzen drückt, werden die nicht benötigten Objekte durch Müll gesammelt. Ich würde mitmachen unset()(anstatt es auf null zu setzen), da es eine bessere Leistung zu haben scheint (nicht getestet, aber in einem der Kommentare aus dem offiziellen PHP-Handbuch dokumentiert).

Beachten Sie jedoch, dass PHP die Objekte immer zerstört, sobald die Seite bereitgestellt wird. Dies sollte also nur bei sehr langen Schleifen und / oder stark intensiven Seiten erforderlich sein.

Frankie
quelle
1
Also Frankie, ich komme aus C ++, wo wir neweinmal verwenden müssen , wenn wir es einmal verwenden delete. Dies ist nicht wahr in PHP? Gibt es eine automatische Speicherbereinigung, wenn das Objekt nicht mehr benötigt wird?
Gsamaras
3
@ gsamaras das stimmt. Sie können jedoch auch Lecks haben, und Sie sollten mehr über den GC von PHP lesen, wenn Sie Dämonen oder ähnliches machen. In den meisten Websites ist die Anfrage so kurzlebig, dass es keine Rolle spielt. php.net/manual/en/features.gc.refcounting-basics.php
Frankie
Does unset()entfernt die Referenz auf das Objekt?
Yousha Aleayoub
9

Ein praktischer Beitrag, der einige Missverständnisse dazu erklärt:

Rufen Sie den Destruktor nicht explizit auf

Dies deckt mehrere Missverständnisse über die Funktionsweise des Destruktors ab. Wenn Sie es explizit aufrufen, wird Ihre Variable laut PHP5-Dokument nicht zerstört:

PHP 5 führt ein Destruktorkonzept ein, das dem anderer objektorientierter Sprachen wie C ++ ähnelt. Die Destruktormethode wird aufgerufen, sobald keine anderen Verweise auf ein bestimmtes Objekt oder in beliebiger Reihenfolge während der Abschaltsequenz vorhanden sind.

Der obige Beitrag besagt, dass das Setzen der Variablen auf Null in einigen Fällen funktionieren kann, solange nichts anderes auf den zugewiesenen Speicher verweist.

sturrockad
quelle
2

Kurze Antwort: Beides wird benötigt.

Ich habe das Gefühl, dass die richtige Antwort nur minimal gegeben wurde. Ja, im Allgemeinen ist unset () am besten für "Geschwindigkeit" geeignet, aber wenn Sie sofort Speicher zurückfordern möchten (auf Kosten der CPU), sollten Sie null verwenden.

Wie bereits erwähnt, bedeutet das Setzen auf Null nicht, dass alles zurückgefordert wird. Sie können Objekte mit gemeinsamem Speicher (nicht geklont) verwenden, um die Zerstörung des Objekts zu verhindern. Darüber hinaus können Sie, wie andere gesagt haben, die Objekte ohnehin nicht explizit "zerstören", sodass Sie es trotzdem nicht versuchen sollten.

Sie müssen herausfinden, welches für Sie am besten ist. Sie können __destruct () auch für ein Objekt verwenden, das bei unset oder null aufgerufen wird, aber es sollte sorgfältig verwendet werden und, wie andere sagten, niemals direkt aufgerufen werden!

sehen:

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

Was ist der Unterschied zwischen der Zuweisung von NULL und nicht gesetzt?

Mike Q.
quelle
0

Dies ist ein einfacher Beweis dafür, dass Sie ein Objekt nicht zerstören können, sondern nur einen Link zu ihm.

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

kehrt zurück

2

Sehen Sie es hier in Aktion: https://eval.in/1054130

Jewgenij Afanasjew
quelle
3
Richtig, Sie haben zerstört, $var2worauf Bezug genommen wurde $var. Jetzt $varzerstörst du auch und vorausgesetzt, es gibt keine anderen Referenzen, die das Objekt enthalten, bist du fertig.
i336_
4
Sie zerstören kein Objekt, Sie zerstören einen Zeiger auf das Objekt. Es ist ein großer Unterschied.
Jewgenij Afanasjew
1
In anderen Sprachen können Sie ein Objekt zerstören und alle anderen Zeiger geben Ihnen Ausnahmen oder Müll, aber es ist kein Fall für PHP
Jewgenij Afanasjew
1
Du kannst nicht zerstören. Wenn es keine Referenz gibt, die das Objekt enthält, kann das Objekt vom Garbage Collector gesammelt werden. Und Sie können nicht zwingen, den Garbage Collector auszuführen.
Daniel
0

Möglicherweise befinden Sie sich in einer Situation, in der Sie ein neues mysqli-Objekt erstellen.

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

aber auch nachdem Sie das Objekt geschlossen haben

$MyConnection->close();

Wenn Sie print_r()den Inhalt von verwenden $MyConnection, wird folgende Fehlermeldung angezeigt:

Error:
mysqli Object

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

In diesem Fall können Sie nicht verwenden, unlink()da unlink()eine Pfadnamenzeichenfolge erforderlich ist, in diesem Fall $MyConnectionjedoch ein Objekt.

Sie haben also eine andere Möglichkeit, den Wert auf null zu setzen:

$MyConnection = null;

Jetzt läuft alles richtig, wie Sie es erwartet haben. Sie haben keinen Inhalt in der Variablen $MyConnectionund haben das mysqli-Objekt bereits bereinigt.

Es wird empfohlen, das Objekt zu schließen, bevor Sie den Wert Ihrer Variablen auf festlegen null.

Subrat Kumar Palhar
quelle
-7

Ich würde mit unset gehen, weil es dem Garbage Collector einen besseren Hinweis geben könnte, damit der Speicher früher wieder verfügbar sein kann. Achten Sie darauf, dass alle Dinge, auf die das Objekt verweist, entweder andere Referenzen haben oder zuerst deaktiviert werden, da Sie sonst wirklich auf den Garbage Collector warten müssen, da diese dann keine Handles enthalten.

Hackartist
quelle
16
Sofern Sie nicht über Quellen verfügen, um Ihre Antworten zu sichern, sollten Sie wahrscheinlich nicht veröffentlichen, was Ihrer Meinung nach "passieren" könnte. Es ist nicht nützlich und führt dazu, dass diese Art von Fehlinformationen als wahr angesehen und wiederholt werden.
Meagar
1
@meagar das ist der genaue Grund, warum ich auf die offizielle Handbuchseite verlinkt habe, wo es in den Kommentaren einen Beispieltest gibt, der unset () mit null vergleicht.
Frankie