Webstatt.org - Community seit 2006 - 2012 (2024?)

clone

Avatar user-168
17.04.2006 16:28

Und schon wieder habe ich eine Verständnisfrage. Ich schreibe mir gerade eine Template-Class und dazu brauche ich den Selbstaufruf der Class.

Ich will also innerhalb einer Class eine Variable haben, in der ich die class als neues Objekt ablege. Meine Ahnungslosigkeit auf Grund von sehr seltsamen Tutorialstexten ist nun:
Werden Variablen bei clone mitkopiert und alles andere, was da irgendwie eingestellt wird, oder sind die variablen leer und er macht nur, was ggf. in __clone steht?

Danke schonmal. :]

Dustwolf ------------------------- Und wenn du lange in einen Abgrund blickst, blickt der Abgrund auch in dich hinein. F. Nietzsche
Avatar user-255
17.04.2006 16:55

Gegenfrage: Würde die Funktion "clone" heißen, wenn nicht das komplette Objekt mit seinen Attributen kopiert werden würde? (:

Nachzulesen wäre der Spaß - wie immer - im Manual.

Those who can, do. Those who can't, teach. # Musik gehört dem Volk! # last.fm
Avatar user-168
17.04.2006 19:51

Da hab ich es auch nachgelesen. Aber irgendwie schaue ich mir dann mal andere Scripte an und stelle ganz schnell fest, entweder die fuschen da rum, oder man kann mit clone noch irgendwie anders neue Instanzen erstellen.

Wie schaffe ich es denn, dass sich eine Class in sich selbst erstellen kann. Also ohne "klonen". Fettes Grinsen

Dustwolf ------------------------- Und wenn du lange in einen Abgrund blickst, blickt der Abgrund auch in dich hinein. F. Nietzsche
Avatar user-255
17.04.2006 20:37

Vielleicht mit clone $this?

Those who can, do. Those who can't, teach. # Musik gehört dem Volk! # last.fm
Avatar user-168
18.04.2006 09:44

Irgendwie will der nit so, wie ich will.
Ich lege nun in der (private) Variablen objekte ein Objekt an:


protected function elemente(){
# Die Funktion legt ggf. Unterobjekte an und setzt somit Vorlagen in Templatelisten um.
preg_match_all('#<!--\s*ANFANG\s+(.*)\s*-->(.*)<!--\s*ENDE\s+(\\1)\s*-->#s',
$this->template,
$elemente);
for($i = 0; $i < count($elemente[1]); $i++){
$this->objekte[$elemente[1][$i]] = clone($this);
if(is_object($this->objekte[$elemente[1][$i]])) echo 'Object angelegt<br>';
$this->objekte[$elemente[1][$i]]->vorlage($elemente[2][$i]);
$this->template = preg_replace('#<!--\s*ANFANG\s+'.$elemente[1][$i].'\s*-->'.$elemente[2][$i].'<!--\s*ENDE\s+'.$elemente[1][$i].'\s*-->#s',
'{'.$elemente[1][$i].'}',
$this->template);
}
}

Da gibt er mir dann auch immer an: Objekt angelegt. Wenn ich nun aber

public function block($id){
foreach($this->objekte as $key => $value) echo $key.'_'.$value.'<br>';
echo $this->name.'_'.$id; # Verweis auf ein Unterobjekt.
if(is_object($this->objekte[$id]))
return $this->objekte[$id];
else
die('<b>Fehler im Templatesystem:</b><br>Nicht existierendes Element_'.$id.'_ in _'.$this->name.'_ aufgerufen!'zwinkern;
}


aufrufe, dann kennt er angeblich die Objekte nimmer. Per foreach gibt er die zwar aus mit
liste _Object id #2
liste2 _Object id #3

aber dann folgt auch schon
Fehler im Templatesystem:
Nicht existierendes Element_liste_ in _Template_ aufgerufen!


Wieso erkennt er das Objekt als Objekt, aber irgendwie auch nicht? ;(

Dustwolf ------------------------- Und wenn du lange in einen Abgrund blickst, blickt der Abgrund auch in dich hinein. F. Nietzsche
Avatar user-255
18.04.2006 10:07

Seltsam. Und als Referenz?
$a =& clone($b);
oder
$a =& $b->__clone();

Those who can, do. Those who can't, teach. # Musik gehört dem Volk! # last.fm
Avatar user-168
18.04.2006 10:23

Also soll ich $b als get_class() verstehen? Weil ansonsten spuckt er mir ohnehin endlos Fehler aus. Bzw. ne Referenz kann ich doch erst erstellen, wenn das Objekt schon besteht, oder versteh ich das falsch.

Ich versuche mir das wie Delphi-classes vorzustellen, weil wir die in der Schule schon gelernt haben... Ggf heißt Referenz hier aber auch was anderes. Fettes Grinsen

(Müsste nach dem & nicht ohnehin ein new stehen???)

Dustwolf ------------------------- Und wenn du lange in einen Abgrund blickst, blickt der Abgrund auch in dich hinein. F. Nietzsche
Avatar user-253
18.04.2006 10:51

Nein Referenz heisst hier genau das gleiche - eben ein Zeiger. Allerdings ist eine explizite Zuweisung per Referenz seit PHP5 nicht mehr nötig, da Objetke nun immer als Referenz übergeben werden.

Leider sitze ich gerade beim Arbeiten und kann daher nicht den ganzen Thread lesen... Allerdings sei erwähnt, dass clone viel mehr als eine neue Instanz erstellt, es werden ja auch die Werte der Attribute kopiert. Eine neue Instanz erstellst du ganz normal mit new. Es spricht auch nichts dagegen innerhalb einer Klasse neue Instanzen derselben zu erstellen und diese in Attributen zu speichern.

Wenn ich dein Codestück richtig interpretieren, suchst du in deinem Templatesyste nach "Untertemplates" und willst diese als Objekt in einem Attribut der übergeordneten Templateklasse speichern. Das klappt dann prima, wenn diese im Konstruktor das Template als String erhält; angenommen deine Templateklasse heisst template dann wäre dies ja einfach so:
$this->objekte[$elemente[1][$i]] = new template($elemente[2][$i]);

Vermutlich ist das Argument aber ein Dateiname. user-158n würde ich empfehlen von dieser Klasse zu erben und nur den Konstruktor bzw ggf die Methode zum einlesen zu überschreiben.

Viele Grüße,
Michael

P.S.
$object = &new classname ist gleich $object =& new classename und seit PHP5 identisch mit $obect = new classname
Hier spuckt die Schreibweise mit & sogar eine Warnung oder Notice aus

Avatar user-168
18.04.2006 11:39

Ajo, also das ist auch so angedacht. Mitlerweile habe ich clone soweit ausgetestet. Fettes Grinsen

Also, zu start lege ich per __construct eine Templateklasse an, wobei in $template der Dateiinhalt gelesen wird, $inhalt die Platzhalter und Inhalte bekommt und $objekte die Subtemplates. Also zum Beispiel eine Tabellenzeile zum dublizieren.

Wenn ich so ein Untertemplate habe, verwende ich nun clone($this) und setze dann die Variablen von oben per unset auf ''. Also nix. zwinkern
Dann hau ich statt wie im constructor den Inhalt (hier mal die Tabellenzeile) wieder in die $template und lasse wieder nach Untertemplates suchen.

Sprich es werden solange Objekte ineinander verschachtelt, bis alle Ebenen abgearbeitet sind.

Die oben genannte Tabellenzeile würde also in:
$this->objekte['tabellenzeile'] als eigentständiges Objekt sitzen. Dieses würde ich dann per Ausgabe in die übergeordnete Templateclass einsetzen. Also quasi ich lasse das Unterobjekt eine Ausgabe vornehmen und packe diese im entsprechenden Platzhalter in $this->inhalt.
Soweit so gut. Laut Ausgabe von PHP hat er die Objekte auch brav erstellt und der Inhalt stimmt auch.

Wenn ich nun aber die Tabellenzeile füllen will und dazu auf das Objekt im Templateobjekt verweise, dann kommt es zum Fehler.
Aber laut Theorie sollte es doch genügen, per return das $this->objekte[...] an eine Variable im eigentlichen Seitenscript zu übergeben.
Also, dass ich quasi das Objekt der Tabellenzeile durch die eigentliche Template-Class durch direkt anspreche.

Ich bin irgendwie ratlos. Vllt. findet ihr ja einen Fehler in meiner theoretischen Lösung. Ansonsten poste ich heut nachmittag mal mein ganzes Templatesystem. So lang ist das nit.

Dustwolf ------------------------- Und wenn du lange in einen Abgrund blickst, blickt der Abgrund auch in dich hinein. F. Nietzsche
Avatar user-253
18.04.2006 12:06

Original von user-168
Wenn ich so ein Untertemplate habe, verwende ich nun clone($this) und setze dann die Variablen von oben per unset auf ''. Also nix. zwinkern


Genau dafür ist clone nicht gedacht zwinkern
Prinzipiell ist deine Idee super, sinnvoll objektorientiert. Aber warum erstellst du nicht anstelle mittels clone mit new wirklich neue Instanzen mit leeren Attributen? Das wäre viel passender.

Michael

Avatar user-168
18.04.2006 13:36

Also, ich konnte das reparieren. Der Fehler lag an unerwarteter Stelle: Beim Regexausdruck. Der hat da unbemerkt nen Leerzeichen mit reingezogen, dass man bei der Standardschriftgröße und -farbe im FF nit so leicht erkennen konnte. Er hat quasi das Objekt liste + Leerzeichen gestartet und ich habs mit liste ohne Leerzeichen am Ende versucht.

Die sollten da nen auto-trim() einbauen.^^

Trotzdem user-158ke und ich habe das clone nu trotzdem rausgeworfen. Jetzt ist zwar meine construct-Funktion sehr groß geworden, aber das passt schon. Fettes Grinsen

Dustwolf ------------------------- Und wenn du lange in einen Abgrund blickst, blickt der Abgrund auch in dich hinein. F. Nietzsche
Avatar user-253
18.04.2006 13:55

Falls du daran interessiert OOP weiter zu vertiefen, könntest du über folgenden sinnvollen Schritt nachdenken:

Du benutzt für die neuen Unterobjekte (,die du jetzt nicht mehr per clone erstellst zwinkern) eine neue Klasse, die von der "normalen" erbt und nur den Konstruktor überschreibt. Auf diesem Wege müsstest du im Konstruktor nicht beide Fälle abfangen sondern hättest dies durch die Klassenstruktur geregelt.

Viele Grüße,
Michael

Avatar user-168
18.04.2006 14:22

Das wär mal zu überlegen. Ich werde die nächsten Tage über noch einige andere Objekte schreiben und dann mal schauen, ob ich da noch das ein oder andere dran abrunde.
Jetzt kommen erstmal Datenbank- und Text-Objekte dran. user-158n noch nen Counter/Statistik und ne Stoppuhr.
Dann hab ich alle Basisfunktionen für meine Websites in Classes gepackt und muss die nit immer neu schreiben und anpassen. Das wird nu alles superdynamisch.

Haste außer dem Manual noch nen gutes Tutorial zu classes? Ich muss mal schauen, eventuell hab ich da noch eins gesehen, wo ich das mit den Regex nachgelesen habe. Weil wenn ich das nu schon mache, dann will ich da nicht noch Fehler und umständliche Codestücke reinbauen. Fettes Grinsen

Dustwolf ------------------------- Und wenn du lange in einen Abgrund blickst, blickt der Abgrund auch in dich hinein. F. Nietzsche