Ja, ist mir klar, dass du den kennst. Ich dachte, weil wir hier die Begrifflichkeiten teilweise durcheinander gewürfelt haben, schreibe ich's mal einmal sauber auf.
destrutor problem
Einklappen
X
-
Ich kenn den Unterschied zwischen Referenz und Object-Identifier und zwischen unset und Zuweisung. Aber trotzdem danke für die ausführliche Schilderung. Dafür war ich selber zu bequem
Wie du schön gesagt hast, wenn man nur Referenzen verwendet, kann man Objekte (fast) zuverlässig löschen. Nur haben Referenzen so viele mögliche Seiteneffekte, dass man besser die Finger davon lässt.
Einen Kommentar schreiben:
-
Zitat von h3llObjekte werden in PHP immer als Referenz übergeben. OK, es ist keine richtige Referenz, …
(„Objektvariable“ meint hier: eine Variable, deren Wert ein Object Identifier ist. Public/private/protected Variablen innerhalb einer Klasse sind für mich Instanzvariablen.)
Die Parameterübergabe sowohl von primitiven Datentypen (float, string, …) als auch von Objekten geschieht standardmäßig als Call-by-value. Auch Objekte werden nur dann by-reference übergeben, wenn dies durch das &-Zeichen in der Funktionssignatur explizit vermerkt ist. Der Inhalt (im Sinne von value) einer Objektvariable sind nicht die Instanzdaten selbst, sondern eine Art Ressourcen-Kennung (Object-Identifier), über die PHP auf die Instanzdaten zugreift.
PHP-Code:// Call-by-value
function f($a) {
$a = null;
}
// Call-by-reference
function g(&$a) {
$a = null;
}
$s = 'foo'; f($s); var_dump($s); // string(3) "foo"
$s = 'foo'; g($s); var_dump($s); // NULL
$o = new stdClass(); f($o); var_dump($o); // object(stdClass)#1 (0) { }
$o = new stdClass(); g($o); var_dump($o); // NULL
Noch kurz zur Verdeutlichung:
Zitat von h3ll…aber trotzdem werden Objekte nicht immer gelöscht, nur weil man eine Variable auf NULL setzt…
PHP-Code:$a = new stdClass();
$b = $a;
$b = null;
var_dump($a, $b); // object(stdClass), NULL
$c = new stdClass();
$d = &$c;
$d = null;
var_dump($c, $d); // NULL, NULL
…oder unset() verwendet. Das sollte einem bewusst sein.
PHP-Code:$e = new stdClass();
$f = $e;
unset($f);
var_dump($e, $f); // object(stdClass), NULL
$g = new stdClass();
$h = &$g;
unset($h);
var_dump($g, $h); // object(stdClass), NULL
Einen Kommentar schreiben:
-
Zitat von fireweasel Beitrag anzeigen"Unsauber" ist vielleicht nicht das passende Wort.
(PHP-)Referenzen bleiben "zählbar", wenn man sie vernünftig einsetzt. Für Objekte und "Resourcen" benötigt man keine (expliziten) Referenzen. Bei Arrays kommts auf den Einzelfall an.
Auch macht es selten Sinn Variablen auf NULL zu setzen, weil sie am Ende jeder Funktion sowieso automatisch gelöscht werden. Wie gesagt, die Variablen, und nicht unbedingt die Objekte. Es ist nur unnötige Schreibarbeit. Und globale Variablen sollte man sowieso nicht verwenden.
Das selbe gilt für Objektvariablen. Wenn ein Objekt gelöscht wird, werden auch automatisch alle Objektvariablen gelöscht. Deswegen ist es auch ziemlich sinnlos sie im Destruktor nochmal explizit zu löschen bzw. auf NULL zu setzen.Zuletzt geändert von h3ll; 07.09.2011, 06:41.
Einen Kommentar schreiben:
-
Ninja-Edit @fireweasel: Ich habe mit dieser Antwort gerade übelste Race Conditions bezüglich deiner Edits. Sorry dafür.
Hast du den Satz mit Stack Overflow wieder rauseditiert? Na ja, egal.
(Verlinkter Artikel: Parameter passing in Java - by reference or by value?. Durchaus interessant zu lesen.)
Das predige (auch) ich seit langem.[1]
Zitat von fireweaselIn allen anderen Fällen auch. Sämtliche anderen Variablen, die dieses Objekt referenzieren, zeigen dann auch auf null.
Referenzen spielen bei Objekten in aller Regel absolut keine Rolle.
Es ist schon bemerkenswert, wie sehr man sich auch als gestandener PHP-Programmierer dabei immer wieder in Definitionen oder ungenauer Ausdrucksweise verheddert.[2]
[1] Schamlos!
[2] Die Aussage beziehe ich natürlich zuerst auf mich selbst.
Einen Kommentar schreiben:
-
Zitat von h3ll Beitrag anzeigenAbgesehen von "cyclic references" sollte das aber möglich sein. Wenn nicht, ist irgendwas am Code unsauber.
(PHP-)Referenzen bleiben "zählbar", wenn man sie vernünftig einsetzt. Für Objekte und "Resourcen" benötigt man keine (expliziten) Referenzen. Bei Arrays kommts auf den Einzelfall an.Zuletzt geändert von fireweasel; 06.09.2011, 23:44.
Einen Kommentar schreiben:
-
Zitat von ApoY2k Beitrag anzeigenNajo es wird doch gelöscht in der Funktion. Oder nur die Referenz? Das ist ja genau was ich frage.
Bin grade leider nicht an einem gescheiten Rechner deshalb konnt ichs nicht selbst ausprobieren x)
Einen Kommentar schreiben:
-
Najo es wird doch gelöscht in der Funktion. Oder nur die Referenz? Das ist ja genau was ich frage.
Bin grade leider nicht an einem gescheiten Rechner deshalb konnt ichs nicht selbst ausprobieren x)
Einen Kommentar schreiben:
-
Zitat von ApoY2k Beitrag anzeigenTestausgaben gehen nicht, weil natürlich nach cube $arr im PHP-Scope nicht mehr existiert
Einen Kommentar schreiben:
-
Wo wir grade dabei sind, was passiert eigentlich bei
PHP-Code:function cube(&$array)
{
foreach ($array as &$val)
unset($val);
unset($array);
}
$arr = array(1, 2, 3);
cube($arr);
Testausgaben gehen nicht, weil natürlich nach cube $arr im PHP-Scope nicht mehr existiert, aber was passiert hinter den Kulissen?
Einen Kommentar schreiben:
-
Zitat von fireweasel Beitrag anzeigenAbgesehen von "cyclic references" sollte das aber möglich sein. Wenn nicht, ist irgendwas am Code unsauber.
Zitat von fireweasel Beitrag anzeigenJetzt enttäuschst du mich aber:
$object = null;
PHP-Code:$object = new FooBar();
$blackbox->doSomething($object);
$object = null;
// Ob hier das Objekt zerstört wurde, weiß man nicht. Es könnte noch immer existieren.
Zuletzt geändert von h3ll; 06.09.2011, 07:29.
Einen Kommentar schreiben:
-
Destruktoren zum Abräumen von Member-Objekten sind nach meinem Verständnis ein Konzept von Sprachen ohne Garbage Collection, in denen es in der Verantwortung des Programmierers liegt, den Speicher von Objekten freizugeben. Ich habe das zuletzt in Delphi gemacht. Java würde ich in der Hinsicht in dieselbe Ecke wie PHP stellen: Das übernimmt die GC.
Zitat von fireweaselIn den Destruktor gehört prinzipiell die "Umkehrfunktionalität" des Konstruktors, sprich: Freigabe von belegten Ressourcen, Aufruf der Destruktoren von Unterobjekten usw.
Threads wie dieser beschreiben das vielleicht ganz gut:
- Is there a destructor for Java? - Stack Overflow
Zitat von Garth GilmourThere is an inherited method called finalize, but this is called entirely at the discretion of the garbage collector. So for classes that need explicit tidy up the convention is to define a close method and use finalize only for sanity checking (i.e. if close has not been called do it now and log an error).
Zitat von mo78Naja aber irgendwie wird der destructor schon gleich beim ersten Aufruf der Seite ausgeführt. Was er aber erst soll nachdem $x==1 ist und die seite neu geladen wurde.
Zitat von fireweasel$object = null;
ist was anderes als
unset ($object);
Edit: Grübel. Objektvariablen sind keine Pointer.Zuletzt geändert von mermshaus; 05.09.2011, 22:08.
Einen Kommentar schreiben:
-
Zitat von fireweasel Beitrag anzeigenAuf einem Webserver können durchaus mehrere Scripts gleichzeitig laufen, die ein und diesselbe Ressource (Datei, Datenbankverbindung usw.) benutzen, oder?
In den Sonderfällen, wo ich damit rechne, dass etwas länger dauert, gebe ich natürlich Ressourcen auch explizit wieder frei - bspw. mit einem session_write_close, wenn anchließend ein länger dauernder Dateidownload ausgegeben wird, o.ä.
Einen Kommentar schreiben:
-
Zitat von wahsaga Beitrag anzeigenGut, aber wenn $object nur eine Referenz von mehreren ist, destroyed das auch nicht wirklich.
ist was anderes als
unset ($object);
Klar, aber PHP im Web gewöhnlich nix Multitasking.
Insofern lautet die Regeln in dem Umfeld eher Crap anywhere you like, this toilet’s gonna explode in 30 seconds anyway …
Einen Kommentar schreiben:
-
Zitat von fireweasel Beitrag anzeigenJetzt enttäuschst du mich aber:
$object = null;
... und ich komme aus einer Welt, in der die wichtigste Grundregel lautet: Gib belegte Ressourcen wieder frei, weil in einem Multitaskingsystem andere Tasks (Prozesse) sie benötigen könnten. Ähnlich wie in dem Spruch:
Verlassen Sie diesen Raum so, wie Sie ihn vorzufinden wünschen.
Insofern lautet die Regeln in dem Umfeld eher Crap anywhere you like, this toilet’s gonna explode in 30 seconds anyway …
Einen Kommentar schreiben:
Einen Kommentar schreiben: