Objekte in einer Klasse erzeugen und deren Zugriff
Oliver
- php
0 Bademeister0 Oliver0 Bademeister0 Oliver
0 Oliver
Hallo liebe SelfHTML Community,
ich versuche gerade mich in die OOP von php einzuarbeiten. Ich bin kein Profi, doch ab und an überkommt mich einfach die Lust mir das ein oder andere kleine Tool für mich zu basteln.
Ich versorge euch erstmal mit dem Quellcode.
<?php
class myCollection{
public function createCollection($collection){
foreach($collection as $key => $value){
$this->object[$key] = $value;
}
}
public function getObject($objectNumber = NULL){
if(!$objectNumber == NULL){
return $this->object[$objectNumber];
}
else{
return $this->object;
}
}
}
class myAnimal{
public function setGender($var){
$this->Gender = $var;
}
public function getGender(){
return $this->Gender;
}
}
$x = new myCollection;
$x->createCollection(array(1,2,3,4,5,6,7,8));
foreach($x->getObject() as $k){
${$k} = new myAnimal;
}
${$x->getObject(2)}->setGender('männlich');
echo ${$x->getObject(2)}->getGender();
Zu Erklärung.
Die Größe des Arraya um mir eine Collection zu erzeugen ist variabel. Nun möchte ich mir zu der Collection die einzelnen Objekte erzeugen.
Ich wollte die Objekte eigentlich gleich in der Klasse myCollection erzeugen. Habe dann aber anschließend im Script keinen Zugriff auf das Objekt, da es scheinbar nicht vorhanden ist.
Kann mir einer verraten wo ich den Denkfehler habe?
So wie es jetzt oben zu sehen sieht der Quellcode aus und fnuktioniert auch.
Ich wollte es eigentlich soo machen. Funktioniert aber nicht.
<?php
class myCollection{
public function createCollection($collection){
foreach($collection as $key => $value){
$this->object[$key] = $value;
}
self::createObjects();
}
private function createObjects(){
foreach(self::getObject() as $key){
${$key} = new myAnimal;
}
}
public function getObject($objectNumber = NULL){
if(!$objectNumber == NULL){
return $this->object[$objectNumber];
}
else{
return $this->object;
}
}
}
...
Vielleicht kann mir da jemand von euch helfen?
Danke
MfG
Oliver
Hi Oliver.
Mal gerade ein paar Anregungen zu Deinem Code:
> public function createCollection($collection){
> foreach($collection as $key => $value){
> $this->object[$key] = $value;
> }
> }
1.: Wieso nicht einfach "$this->object = $collection"?
2.: Wieso soll das nicht der Konstruktor machen? (Das ist ne echte Frage - es könnte dafür u.U. Gründe geben. Mein Tipp ist aber, dass es keine gibt. Ein Hinweis darauf ist bereits der Name der Funktion - kreiert wird die Collection bereits dann, wenn das Objekt kreiert wird. Oder?
> public function getObject($objectNumber = NULL){
> if(!$objectNumber == NULL){
> return $this->object[$objectNumber];
> }
> else{
> return $this->object;
> }
> }
> }
1.: Vorsicht: Dein Array Object kann einen Schlüssel 0 haben. Den willst Du wohl von null unterschieden, also if (!$objectNumber === NULL)
2.: In Wahrheit willst Du aber einen Operator nehmen statt zwei, wenn einer reicht: if ($objectNumber !== NULL)
3.: Es ist selten ratsam, dass eine Funktion Rückgabewerte verschiedener Variablentypen erlaubt (zumindest solche, die sich nicht auf "natürliche Weise" per impliziter Typumwandlung vereinbaren lassen). Willst Du wirklich, dass eine Funktion, die getObject heißt, u.U. das ganze Array zurückgibt? Ich würde dafüer eine eigene Funktion vorsehen.
$x = new myCollection;
$x->createCollection(array(1,2,3,4,5,6,7,8));
S.o. Warum nicht $x = new myCollection(array(1,2,3,4,5,6,7,8))
foreach($x->getObject() as $k){
${$k} = new myAnimal;
}
Was soll das? Warum willst Du außerhalb der Objektes Deine Animals anlegen? Und: Die Namen Deiner Variablen sind ungültig. Es gibt hier auch keinen guten Grund, variable Variablen anzulegen.
${$x->getObject(2)}->setGender('männlich');
echo ${$x->getObject(2)}->getGender();
Lass um Gottes willen die variablen Variablen weg!
Zu Erklärung.
Die Größe des Arraya um mir eine Collection zu erzeugen ist variabel. Nun möchte ich mir zu der Collection die einzelnen Objekte erzeugen.
Wozu ist denn diese Collection überhaupt da? Was soll sie können, was ein Array nicht kann?
Ich wollte die Objekte eigentlich gleich in der Klasse myCollection erzeugen. Habe dann aber anschließend im Script keinen Zugriff auf das Objekt, da es scheinbar nicht vorhanden ist.
?? Und unscheinbar?
Kann mir einer verraten wo ich den Denkfehler habe?
So wie es jetzt oben zu sehen sieht der Quellcode aus und fnuktioniert auch.
Dass das funktioniert - ich hab gerade mal getestet - hast Du wohl einem Bug zu verdanken. Deine Variablennamen sind ungültig. Du kriegst die Variablen auf diese Weise der variablen Referenzierung tatsächlich erstellt und auch ins $GLOBALS-Array rein, aber Du wirst nicht direkt auf sie zugreifen können, sondern nur wieder über diese Krücke. Schreibe die Dinger *unbedingt* in ein Array!
Ich wollte es eigentlich soo machen. Funktioniert aber nicht.
private function createObjects(){
foreach(self::getObject() as $key){
${$key} = new myAnimal;
Was ist wohl der Scope der hier angelegten Variablen?
Wozu denn diese ganze Collection-Sache?
Viele Grüße,
der Bademeister
Hallo Bademeister,
danke vorerst für deine Hinweise und die Fragen, die ich versuche hiermit zu beantworten.
Wie ich bereits in meinem Posting vorher schrieb, versuche ich gerade etwas oop in php.
Ich hole mal etwas weiter aus um das Vorhaben zu erklären.
Ich züchte zu Hause Kaninchen. :) Auch zum Eigenverzehr. Ich mögt mir das bitte Nachsehen.
Das kleine Projekt soll mir helfen meine Kaninchen zu verwalten. Sind nun mal nicht nur 20 Stück.
Diese Kaninchen liegen mit diversen Daten(id, boxnr, geburtstag, usw.) in einer MySQL Datenbank.
Jedes Kaninchen stellt für mich ein Objekt dar. Es kann _umziehen_ von Box 2 in die Box 5, durchaus auch mal krank sein oder eben tragend.
Das möchte ich gern mit oop realisieren.
Soweit richtig gedacht?
Wie erwähnt haben die Kaninchen keine Namen sondern nur Nummern (id in der DB).
Die Funktion
... CreateCollection(array(Kaninchen1,Kaninchen2) ...
soll die Menge an Kaninchen in meinem Besitz darstellen und Ihnen Namen geben über die ich dann mit der Klasse myAnimal die Eigenschaften zu den jeweiligen Tieren anlege. Es kommen und gehen ständig Tiere und kann im Quellcode so leider nicht schreiben:
$Kaninchen1 = new myAnimal;
$Kaninchen2 = new myAnimal;
$Kaninchen3 = new myAnimal;
$Kaninchen4 = new myAnimal;
$Kaninchen5 = new myAnimal;
Es könnten durchaus mal 20 Stück sein oder 50. Ich will dafür nicht immer im Code rumschreiben. So solls ja auch nicht sein.
Dafür gibts sicher eine Lösung.
Bisher dachte ich mir das so:
Die Collection sammelt die Objektnamen (Kaninchen1, Kaninchen+n) der Tiere.
$Kaninchen1 = new myAnimal;
$Kaninchen1->setGender('weiblich');
$Kaninchen2 = new myAnimal;
$Kaninchen2->setGender('männlich');
usw.
Bis hierher kannst du mir sicher folgen.
Hast du vielleicht für oben genanntes Problem einen Lösungsvorschlag?
1.: Wieso nicht einfach "$this->object = $collection"?
Na klar. Ist ja schon in Array. :) Und dann gleich ein Neues. Das ist Quatsch.
2.: Wieso soll das nicht der Konstruktor machen? (Das ist ne echte Frage - es könnte dafür u.U. Gründe geben. Mein Tipp ist aber, dass es keine gibt. Ein Hinweis darauf ist bereits der Name der Funktion - kreiert wird die Collection bereits dann, wenn das Objekt kreiert wird. Oder?
... __CONSTRUCT(){
bla blubber blub;
}
Habe ich verstanden kann man so machen. :)
public function getObject($objectNumber = NULL){
if(!$objectNumber == NULL){
return $this->object[$objectNumber];
}
else{
return $this->object;
}
}
}
>
> 1.: Vorsicht: Dein Array Object kann einen Schlüssel 0 haben. Den willst Du wohl von null unterschieden, also `if (!$objectNumber === NULL)`{:.language-php}
>
> 2.: In Wahrheit willst Du aber einen Operator nehmen statt zwei, wenn einer reicht: `if ($objectNumber !== NULL)`{:.language-php}
>
> 3.: Es ist selten ratsam, dass eine Funktion Rückgabewerte verschiedener Variablentypen erlaubt (zumindest solche, die sich nicht auf "natürliche Weise" per impliziter Typumwandlung vereinbaren lassen). Willst Du wirklich, dass eine Funktion, die getObject heißt, u.U. das ganze Array zurückgibt? Ich würde dafüer eine eigene Funktion vorsehen.
Es war vorgesehen, das ich uU. ein Objekt benötige oder gar alle in einem Ritt. Für mehr sollte das nicht dienen.
> > $x = new myCollection;
> > $x->createCollection(array(1,2,3,4,5,6,7,8));
>
> S.o. Warum nicht `$x = new myCollection(array(1,2,3,4,5,6,7,8))`{:.language-php}
>
Durchaus machbar. :)
Wußte ich bereits und habs einfach nur umständlicher umgesetzt.
> > foreach($x->getObject() as $k){
> > ${$k} = new myAnimal;
> > }
>
> Was soll das? Warum willst Du außerhalb der Objektes Deine Animals anlegen? Und: Die Namen Deiner Variablen sind ungültig. Es gibt hier auch keinen guten Grund, variable Variablen anzulegen.
Auch hier war ich erstaunt. Zulässige Variablen in php dürfen laut Doc ja nicht mit einer Zahl beginnen. Komischerweise ging es trotz allem.
> > ${$x->getObject(2)}->setGender('männlich');
> > echo ${$x->getObject(2)}->getGender();
>
> Lass um Gottes willen die variablen Variablen weg!
Ich verstehe, aber mein eigentliches Problem findest du oben beschrieben. Deswegen die variablen Variablen. Ich finds auch nciht schön, nur habe ich bisher keine andere Lösung.
> > Zu Erklärung.
> > Die Größe des Arraya um mir eine Collection zu erzeugen ist variabel. Nun möchte ich mir zu der Collection die einzelnen Objekte erzeugen.
>
> Wozu ist denn diese Collection überhaupt da? Was soll sie können, was ein Array nicht kann?
siehe oben.
> > Ich wollte die Objekte eigentlich gleich in der Klasse myCollection erzeugen. Habe dann aber anschließend im Script keinen Zugriff auf das Objekt, da es scheinbar nicht vorhanden ist.
>
> ?? Und unscheinbar?
Kann dir nicht folgen!
> > Kann mir einer verraten wo ich den Denkfehler habe?
> > So wie es jetzt oben zu sehen sieht der Quellcode aus und fnuktioniert auch.
>
> Dass das funktioniert - ich hab gerade mal getestet - hast Du wohl einem Bug zu verdanken. Deine Variablennamen sind ungültig. Du kriegst die Variablen auf diese Weise der variablen Referenzierung tatsächlich erstellt und auch ins $GLOBALS-Array rein, aber Du wirst nicht direkt auf sie zugreifen können, sondern nur wieder über diese Krücke. Schreibe die Dinger \*unbedingt\* in ein Array!
Ein blindes Huhn findet auch mal einen BUG. :)
> > Ich wollte es eigentlich soo machen. Funktioniert aber nicht.
> >
> > ~~~php
> > private function createObjects(){
> > foreach(self::getObject() as $key){
> > ${$key} = new myAnimal;
>
Was ist wohl der Scope der hier angelegten Variablen?
Scope, verzeih mir bitte, das muss ich erstmal googlen.
Was ist das?
In der Hoffnung das alles etwas verständlicher war, hoffe ich nun auf einen Lösungsansatz.
Das muß doch irgendwie machbar sein.
Vielen Dank nochmals Bademeister,
MfG
Oliver
Hi.
Das kleine Projekt soll mir helfen meine Kaninchen zu verwalten. Sind nun mal nicht nur 20 Stück.
Diese Kaninchen liegen mit diversen Daten(id, boxnr, geburtstag, usw.) in einer MySQL Datenbank.Jedes Kaninchen stellt für mich ein Objekt dar. Es kann _umziehen_ von Box 2 in die Box 5, durchaus auch mal krank sein oder eben tragend.
So. Hier erstmal kurz anhalten und ueberlegen:
Deine Kaninchen liegen in der Datenbank! Wenn Du jetzt wasAuchImmer mit den Kaninchen innerhalb Deines PHP-Skriptes machen willst, dann kriegt dieses Skript ALLE Informationen ueber den aktuellen Bestand der Kaninchen (Anzahl, Krankheiten, u.s.w.) aus der Datenbank. Wenn sich was aendert - neues Kaninchen geboren e.t.c. - dann fuehrt das NIE dazu, dass Du Deinen PHP-Code aendern musst. Wenn doch, dann weisst Du, dass Du etwas falsch gemacht hast.
Das möchte ich gern mit oop realisieren.
Soweit richtig gedacht?
Die Frage muss gestattet sein, WAS Du realisieren willst. Was Du wohl wirklich realisieren willst, ist ein Mechanismus, um die Daten Deiner Kaninchen a) zu lesen und b) zu aendern. Du solltest Dir aber im Klaren sein, dass das nur Einzelaktionen sind. Die Kaninchen leben in der Datenbank, nicht in irgendeinem PHP-Skript (ich haette nicht gedacht, dass ich diesen Satz jemals sagen wuerde ;-)).
Wie erwähnt haben die Kaninchen keine Namen sondern nur Nummern (id in der DB).
Das wirkte im ersten Moment etwas herzlos auf mich, ist aber wahrscheinlich besser, wenn man sie spaeter noch essen will!? ;-)
Die Funktion
... CreateCollection(array(Kaninchen1,Kaninchen2) ...
> soll die Menge an Kaninchen in meinem Besitz darstellen und Ihnen Namen
Das ist kein guter Ansatz. Wie oben bereits gesagt: Wie viele Kaninchen Du hast, weiss die Datenbank! Sonst niemand! Dein Objekt soll eine Liste mit allen Kaninchen repraesentieren. Daher sollte es bei seiner Erstellung (also im Konstruktor) die Datenbank fragen, welche Kaninchen zur Zeit da sind:
~~~php
class MyRabbits {
protected $rabbit = array();
public function __construct() {
- stelle Verbindung zur Datanbank her
- hole per Query alle Kaninchen aus der Datenbank
- fuer jedes Kaninchen:
$this->rabbit[ID des Kaninchens] = new MyAnimal(aktuelles Kaninchen)
}
public function getRabbit($index) {
return $this->rabbit[$index]; // Achtung: [link:http://en.wikipedia.org/wiki/Garbage_In,_Garbage_Out@title=GIGO]
}
public function getRabbits {
return $this->rabbit;
}
}
Es könnten durchaus mal 20 Stück sein oder 50. Ich will dafür nicht immer im Code rumschreiben. So solls ja auch nicht sein.
Eben.
$Kaninchen1 = new myAnimal;
$Kaninchen1->setGender('weiblich');$Kaninchen2 = new myAnimal;
$Kaninchen2->setGender('männlich');
1\.: Nein, nein, nein! Die Kaninchen stehen in einem Array \*in\* dem Objekt, nicht irgendwo als globale Variablen im Skript.
2\.: Sollte das gar nicht mehr noetig sein, weil das Geschlecht des Kaninchens beim Anlegen des Kaninchenobjektes bereits gesetzt wurde: Der Konstruktor der Collection hat beim Auslesen des Kninchens aus der Datenbank das Geschlecht bereits gelesen und gesetzt. Von Hand setzen willst Du es evtl. dann, wenn Du (z.B. durch Auswertung eins Formulares) ein neues Kaninchen erzeugen willst, das gerade geboren wurde, und in die Datenbank eintragen. Das ist aber eh noch ne andere Baustelle.
Und: Es ist ratsam, fuer das Geschlecht (maennlich, weiblich) nicht Strings zu verwenden, sondern Konstanten anzulegen, mit etwa den Werten 0 und 1.
> > 3.: Es ist selten ratsam, dass eine Funktion Rückgabewerte verschiedener Variablentypen erlaubt (zumindest solche, die sich nicht auf "natürliche Weise" per impliziter Typumwandlung vereinbaren lassen). Willst Du wirklich, dass eine Funktion, die getObject heißt, u.U. das ganze Array zurückgibt? Ich würde dafüer eine eigene Funktion vorsehen.
>
> Es war vorgesehen, das ich uU. ein Objekt benötige oder gar alle in einem Ritt. Für mehr sollte das nicht dienen.
Fuer diesen Fall habe ich ja nur empfohlen (und tue das nochmal), dafuer eine eigene Funktion bereitzustellen, deren Funktionsnamen man ansieht, dass sie dazu da ist, das ganze Array zu liefern.
Allerdings: Da das ganze Objekt "Collection" dazu da ist, das Array mit Deinen Kaninchen zu repraesentieren, waere (als etwas ambitionierteres Ziel) evtl. eine Implementierung von [ArrayAccess](http://uk.php.net/manual/en/class.arrayaccess.php) ratsam, so dass Du direkt per Array-Syntax auf die Kaninchen zugreifen kannst.
> > > Ich wollte die Objekte eigentlich gleich in der Klasse myCollection erzeugen. Habe dann aber anschließend im Script keinen Zugriff auf das Objekt, da es scheinbar nicht vorhanden ist.
> >
> > ?? Und unscheinbar?
>
> Kann dir nicht folgen!
Natuerlich hast Du Zugriff auf sie, wenn sie als Variablen in dem Objekt vorhanden und "public" sind. Allerdings solltest Du Dich entscheiden, ob Du sie "public" machst, oder ob Du, wie geschehen, eine Funktion anbietest, die sie zurueckliefert. Beides brauchst Du nicht.
> In der Hoffnung das alles etwas verständlicher war, hoffe ich nun auf einen Lösungsansatz.
S.o.
Viele Gruesse,
der Bademeister
Hallo Bademeister,
Die Kaninchen leben in der Datenbank, nicht in irgendeinem PHP-Skript ...
Den finde ich geil.
Den Satz muß ich mal auf der nächsten Versammlung von mir geben. Dann lebe ich nur noch in der Mitgliedsbüchern. ^^
class MyRabbits {
protected $rabbit = array();
public function __construct() {
- stelle Verbindung zur Datanbank her
- hole per Query alle Kaninchen aus der Datenbank
- fuer jedes Kaninchen:
$this->rabbit[ID des Kaninchens] = new MyAnimal(aktuelles Kaninchen)
} ...
Du hast mir sehr geholfen und ich kann nun weiter an der Verwaltung der Kaninchen arbeiten.
Vielen vielen Dank.
MfG
Oliver
Hallo bademeister,
private function createObjects(){
foreach(self::getObject() as $key){
${$key} = new myAnimal;
>
> Was ist wohl der Scope der hier angelegten Variablen?
Der Geltungsbereich. :)
Ich habe es gelesen, aber nur zum Teil verstanden.
Das mit den Referenzen geht mir nicht in den Kopf.
Kannst du das ggfs. an einem Beispiel erklären? Zumindest verständlicher wie auf der php.net Seite.
Wäre ich dankbar.
MfG
Oliver