PHP5 - Objekte werden nur per Referenz übergeben

Fragen zur Installation von CONTENIDO 4.9? Probleme bei der Konfiguration? Hinweise oder Fragen zur Entwicklung des Systemes oder zur Sicherheit?
Antworten
HerrB
Beiträge: 6935
Registriert: Do 22. Mai 2003, 12:44
Wohnort: Berlin
Kontaktdaten:

PHP5 - Objekte werden nur per Referenz übergeben

Beitrag von HerrB »

Mag vielen klar sein, mich hat es Kopfzerbrechen gekostet:

Keine gute Idee:

Code: Alles auswählen

$oSelObject = cHTMLSelectElement("foo");

...
$oSelObject irgendwie füllen, z.B. mit ->autofill
...

$oSelObjectA = $oSelObject;
$oSelObjectA->machwasmitdemObjekt;

$oSelObjectB = $oSelObject;
$oSelObjectB->machwasanderesmitdemObjekt;
Wozu man sowas braucht? Nun, man konnte es sich leicht machen: Wenn man z.B. für unterschiedliche Aufgaben jeweils über eine Select-Box (die der cHTMLSelectElement-Klasse entstammt) aus einem Baum eine idcat auswählen musste, konnte man das Objekt einmal erzeugen, mit ->updateAttributes (array("name" = "neuerName")) umtaufen und mit ->setDefault einstellen - ein Abfrage, einmal gefüllt, zwei Select-Boxen...

Mit PHP5 geht das nicht mehr: $oSelObject, $oSelObjectA und $oSelObjectB sind eins.

Mögliche Lösung:

Code: Alles auswählen

$oSelObjectA = clone $oSelObject;
$oSelObjectB = clone $oSelObject;
Aber natürlich gibt es clone nur ab PHP5 (hey, es gibt ein clone aus dem PEAR-compat-Paket... toll). Und selbst in PHP5 isses nicht so der Burner, da clone keine 100%ige Kopie ergibt - Referenzen, die im Objekt verwendet werden, bleiben Referenzen - yeah!

Stellen wir uns also dumm und lassen PHP arbeiten:

Code: Alles auswählen

$oSelObjectA = new cHTMLSelectElement("selObjectA");
$oSelObjectB = new cHTMLSelectElement("selObjectB");

...
Das jeweilige $oSelObjectX füllen und zwar mit:

$oOption = new cHTMLOptionElement($Beschriftung, $id);
$oSelObjectA->addOptionElement($id, $oOption);
$oSelObjectB->addOptionElement($id, $oOption);
...

$oSelObjectA->setDefault("EineID");
$oSelObjectB->setDefault("EineAndereID");
Der coole Effekt ist, das zwar jetzt zwei korrekt benannte Select-Boxen ausgegeben werden - die aber immer auf dem gleichen Wert stehen, nämlich auf "EineAndereID" - der ID für Objekt B.

Ist natürlich auch logisch... $oOption enthält nur eine Referenz, auf ein Option-Element, da ja $oOption = new cHTMLOptionElement ($Beschriftung, $id);

Und das hat zur Folge, dass die setDefault-Methode durch die gleiche Parameter-Liste wandert und das gleiche Element auswählt; für beide Boxen...

Wer sich also wundert, so würde es dann gehen:

Code: Alles auswählen

$oSelObjectA = new cHTMLSelectElement("selObjectA");
$oSelObjectB = new cHTMLSelectElement("selObjectB");

...
Das jeweilige $oSelObjectX füllen und zwar mit:

$oOptionA = new cHTMLOptionElement($Beschriftung, $id);
$oOptionB = new cHTMLOptionElement($Beschriftung, $id);
$oSelObjectA->addOptionElement($id, $oOptionA);
$oSelObjectB->addOptionElement($id, $oOptionB);
...

$oSelObjectA->setDefault("EineID");
$oSelObjectB->setDefault("EineAndereID");
Für die Kenner vermutlich ein Achselzucken, für die anderen: zur Info ;-)

Gruß
HerrB
Bitte keine unaufgeforderten PMs oder E-Mails -> use da Forum!

Newsletter: V4.4.x | V4.6.0-15 (Module, Backend) | V4.6.22+
Standardartikelliste: V4.4.x | V4.6.x
http://www.contenido.org/forum/search.php | http://faq.contenido.org | http://www.communido.net
emergence
Beiträge: 10653
Registriert: Mo 28. Jul 2003, 12:49
Wohnort: Austria
Kontaktdaten:

Beitrag von emergence »

wirkt sich auch ziemlich schlecht bei pdfdom aus...
zu dem clone -> gibts ja nur bei php5

wenn man folgendes definiert hat

Code: Alles auswählen

if (version_compare(phpversion(), '5.0') < 0) {
    eval('
        function clone($object)
        {
            // Sanity check
            if (!is_object($object)) {
                trigger_error(\'clone() __clone method called on non-object\', E_USER_WARNING);
                return;
            }

            // If there is a __clone method call it on the "new" class
            if (method_exists($object, \'__clone\')) {
                $object->__clone();
            }

            return $object;
        }
    ');
}
kann man clone so nutzen das es bei php4 auch funktioniert...

schreibweise müsste aber dann immer

Code: Alles auswählen

$oSelObjectA = clone($oSelObject); 
$oSelObjectB = clone($oSelObject);
sein.
*** make your own tools (wishlist :: thx)
Antworten