Ankündigung

Einklappen
Keine Ankündigung bisher.

Zugriff auf aufrufende Klasse

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • BlackWolf
    hat ein Thema erstellt Zugriff auf aufrufende Klasse.

    Zugriff auf aufrufende Klasse

    hiho,
    sitze gerade an folgendem: Ich muss "irgendwie" auf die Klasse zugreifen, die die aktuelle Methode aufgerufen hat.
    Also etwas klarer. Ich habe in etwa sowas:
    PHP-Code:
    class {
      public 
    $value NULL;
      public 
    $fields = array();
      
      public function 
    __construct($value) {
        
    $this->value $value;
        
    $this->fields[] = new B();
    }

    class 
    {
      public function 
    __construct() {
        
    //Hier muss ich auf $value von A zugreifen können
      
    }

    In diesem Beispiel natürlich simpel, ich könnte $value einfach als Parameter übergeben. In realo habe ich allerdings viel mehr Werte die ich nicht alle als Parameter übergeben will. Jetzt hatte ich mir etwas ausgedacht, weiß aber nicht ob das so geschickt ist. Was ich gemacht habe ist einfach
    PHP-Code:
    $this->fields[] = new B(&$this); 
    Nun kenne ich mich mit Referenzen zu Objekten leider nicht so gut aus. Ich meine prinzipiell hab' ich ja jetzt eine Endlosschleife erzeugt. B bekommt die Instanz von A übergeben, diese enthält wiederrum B das wiederrum die Instanz von A übergeben bekommt ... naja und so weiter.

    Meine Frage ist jetzt: Kann man das so machen und wenn ja erzeugt das erheblichen Rechen/Datenaufwand bei PHP? Wie handelt PHP so eine "Endlosschleife"?
    Mein Code funktioniert übrigens, ich kann auch nicht feststellen, dass er besonders langsam läuft, mache mir aber Sorgen das es Probleme mit der Performance geben könnte wenn ich viele B-Objekte erzeuge (die ja alle eine Referenz zu A übergeben bekommen).

    Code gut? Code schlecht?
    Danke
    mfg

  • Manko10
    antwortet
    Wie genau das intern gehandhabt wurde, weiß ich nicht. ein gettype($object) ergibt auch object und nicht array, aber dennoch waren Objekte in PHP 4 und 3 primitive Datentypen, die zumindest wie Arrays behandelt wurden.

    Einen Kommentar schreiben:


  • nikosch
    antwortet
    Wie das denn? Die haben doch auch Methoden?

    Einen Kommentar schreiben:


  • Manko10
    antwortet
    Ja, Meister!
    In PHP 4 gibt es ja aber noch keine richtigen Objekte, da sind das intern nur Arrays.

    Einen Kommentar schreiben:


  • nikosch
    antwortet
    da in PHP generell Referenzen auf Objekte übergeben werden
    Seit PHP5.

    Einen Kommentar schreiben:


  • Manko10
    antwortet
    Den Referenzierungsoperator kannst du dir darüberhinaus auch wirklich sparen, da in PHP generell Referenzen auf Objekte übergeben werden. Um eine Kopie zu erstellen, musst du explizit den clone-Operator verwenden.
    Das lässt sich auch beweisen:
    PHP-Code:
    $a = new Xyz();
    $b $a;

    if (
    $a === $b) {
        print 
    'Dasselbe Objekt';
    } else {
        print 
    'Nicht dasselbe Objekt';

    Ohne new oder clone erstellst du keine neue Instanz. Ein anderer Beweis:
    PHP-Code:
    $a = new Xyz();
    $a->1;

    // ergibt 1
    print $a->b;

    func($a);

    // ergibt 2
    print $a->b;

    function 
    func($obj)
    {
        
    $obj->2;

    Es handelt sich also um dasselbe Objekt. Performanceprobleme wirst du dadurch also nicht bekommen.

    Einen Kommentar schreiben:


  • nikosch
    antwortet
    Ich finde das verständlich. Zumal das Objekt tausendmal nützlicher ist, als eine Liste von Parametern. Schon was zukünftige Weiterentwicklung betrifft. Im konkreten Fall könnte bspw. ein invalides Feld das Form auf invalid schalten oder eine Meldung in einem vom Form verwalteten Messagestack ablegen. Etc pp.

    Hatte vor kurzem einen ähnlichen Fall, in dem ich in einer verschachtelten Baumstruktur auf den jeweiligen Elternknoten zugreifen wollte. Hat auch mit ner Objektreferenz geklappt. print_r und Co geben dann erfreulicherweise nur *Rekursion* aus.

    Einen Kommentar schreiben:


  • BlackWolf
    antwortet
    Zitat von nikosch Beitrag anzeigen
    Ganz einfach: Ihm fehlt das Zugriffsobjekt. Die Methoden sind nicht statisch.

    @Salkin: Ich schätze, das ist ihm schon klar.

    @bw: Die Referenz wird ja nicht weiter verarbeitet, sie wird ja nur zugewiesen. Und wenn sie verarbeitet wird (bspw. in print_r) lotet PHP die Schleifen aus. Ich glaube irgendwo habe ich mal gelesen, dass das nicht immer klappt (war m.E. bei nem var_export oder so)...
    jap, das war mir alles klar, aber trotzdem danke
    das PHP die schleifen verhindert ist eben auch das was ich vermute.

    Zitat von Manko10 Beitrag anzeigen
    Ich habe ihn jetzt aber so verstanden, dass die Übergabe des Objektes selbst kein Problem ist. Er will nur nicht jede Eigenschaft einzeln vergeben und das muss er bei Übergabe des Objekts ja auch nicht.
    Genauso ist es. Meine Frage war jetzt eigentlich nur ob - und wenn ja warum - es zu Problemen kommen kann wenn ich das Objekt als Refrenz übergebe.

    Zitat von David Beitrag anzeigen
    Das Problem (und vermutlich auch die Lösung) wäre spannender, wenn wir wüssten, was da eigentlich passieren soll. Also welche Daten da aus welchem Grund an welcher Stelle wirklich benötigt werden.
    Naja, habs ja oben schonmal kurz angerissen. Habe eine Klasse HTMLForm die eben ein HTML-Formular erstellt. Diese hat jetzt ein Array mit Objekten vom Typ HTMLFormField (eine weitere Klasse). Nun benötige ich in HTMLFormField aber z.B. den Namen des Formulars zu dem das Feld gehört oder auch ob das Formular über POST oder GET gesendet wird (um einen eventuell vom User eingegebenen Wert auslesen zu können). Und deshalb brauche ich in HTMLFormField eben Daten zum Formular zu dem dieses Feld gehört. Zugegeben, einfach einige Parameter an HTMLFormField zu übergeben wäre zwar einfacher, allerdings kommt mir das so ... ungeschickt gelöst vor.

    mfg

    Einen Kommentar schreiben:


  • David
    antwortet
    Das Problem (und vermutlich auch die Lösung) wäre spannender, wenn wir wüssten, was da eigentlich passieren soll. Also welche Daten da aus welchem Grund an welcher Stelle wirklich benötigt werden.

    Einen Kommentar schreiben:


  • Manko10
    antwortet
    Ich habe ihn jetzt aber so verstanden, dass die Übergabe des Objektes selbst kein Problem ist. Er will nur nicht jede Eigenschaft einzeln vergeben und das muss er bei Übergabe des Objekts ja auch nicht.

    Einen Kommentar schreiben:


  • nikosch
    antwortet
    Nein, nicht falscher Thread. Nur frage ich mich, wo das Problem liegt, wenn die Eigenschaften doch eh public sind 8was eigentlich nicht sein sollte).
    Ganz einfach: Ihm fehlt das Zugriffsobjekt. Die Methoden sind nicht statisch.

    @Salkin: Ich schätze, das ist ihm schon klar.

    @bw: Die Referenz wird ja nicht weiter verarbeitet, sie wird ja nur zugewiesen. Und wenn sie verarbeitet wird (bspw. in print_r) lotet PHP die Schleifen aus. Ich glaube irgendwo habe ich mal gelesen, dass das nicht immer klappt (war m.E. bei nem var_export oder so)...

    Einen Kommentar schreiben:


  • Salkin
    antwortet
    Zitat von BlackWolf Beitrag anzeigen
    Naja gut, Speicher verbraucht das ganze natürlich nicht da es ja eine Referenz ist. Allerdings müsste PHP - theoretisch - ja unendlich lange rechnen, da es diese Referenz doch unendlich oft erzeugt, oder? Allerdings scheint es sowas wohl zu erkennen ...
    Wenn du mit php einen Variablen "deklarierst"(also das erste mal verwendest, php macht den rest) wird deinem Variablen ein Platz im Arbeitsspeicher reserviert, wo dann daten reingeschrieben werden können. Damit du diese auch wieder verwenden kannst, muss das Programm auch wissen wo diese Daten stehen, das ist die Adresse.

    Mit dieser Adresse kann php nun auf den Inhalt(also die Daten, zb eine Zahl oder ein Text) zugreifen.

    Dh, jeder Variable verweißt auf eine Adresse im Arbeitsspeicher. Beim arbeiten mit Variablen wird ständig der Inhalt an dieser Adresse wieder herausgelesen oder geschrieben. Wenn du der Funktion den Variablen $a übergibst, so ließt php die Daten aus dem Arbeitsspeicher und schickt sie der Funktion(= eine Kopie, die Variable in der Funktion bekommt eine andere Adresse, wo dann die Kopie reingeschrieben wird). Wenn du aber eine Referenz(&$a) übergibst, so schickt php der Funktion nicht den Inhalt, sondern nur die Information wo dieser Inhalt zu finden ist, also die Adresse. Dh, du hast nun 2 Variablen, die genau auf denselben Punkt im Arbeitsspeicher zeigen, wenn du mit der Funktion den Inhalt änderst, so wird die originalvariable beim nächsten Lesen des Inhalts auch den neuen WErt bekommen. Also hat Php beim Arbeiten mit Referenzen im Prinzip weniger zu tun. (ob das reell auch so ist weiss ich nicht)

    hm, meinst du vielleicht das? Dann wäre es recht einfach:
    PHP: extends - Manual

    Einen Kommentar schreiben:


  • Manko10
    antwortet
    Nein, nicht falscher Thread. Nur frage ich mich, wo das Problem liegt, wenn die Eigenschaften doch eh public sind 8was eigentlich nicht sein sollte).

    Einen Kommentar schreiben:


  • BlackWolf
    antwortet
    Zitat von Manko10 Beitrag anzeigen
    Du kannst nicht auf die privaten Eigenschaften einer anderen Klasse zugreifen. Was du hingegen machen kannst, ist, sie als protected zu deklarieren. Nun muss die eine Klasse von der anderen abgeleitet werden und du hast Zugriff auf die Eigenschaften.
    Eine andere Möglichkeit wäre ein Iterator-Pattern. Bei diesem werden u.a. Getter und Setter definiert. Beim Iterieren über das Objekt kann die Klasse dann entscheiden, welche Eigenschaften sie zur Verfügung stellt.
    hm ... wie kommste jez drauf das meine Eigenschaften private sind? Und ableiten geht auch nicht. Falscher Thread?

    Zitat von nikosch Beitrag anzeigen
    Kommt drauf an. Das & kannste bei php5 weglassen.

    Was auch ginge, wäre ein statisches Array in A, das die Instanzen über einen Schlüssel verwaltet.

    Bspw.
    PHP-Code:
    class {
      private static 
    $instances;

      public 
    $value NULL;
      public 
    $fields = array();
      
      public static 
    getInstance ($key)
        {
        return (
    self::$instances[$key]);
        }

      public function 
    __construct($value
        {
        
    $this->key md5(rand ()); // Bsp. Geht sicher besser
        
    self::$instances[$key] = $this;

        
    $this->value $value;
        
    $this->fields[] = new B($this->key);
        }

    }

    class 
    {
      public function 
    __construct($key) {
        
    $object A::getInstance  ($key);
        
    $object->whatever ();
        
    //Hier muss ich auf $value von A zugreifen können
      
    }

    Natürlich kannst Du die Instanzen auch in einer Registry oder sonsteinem globalen Objekt verwalten. Aber so find ichs schon ganz elegant.
    Hm das gefällt mir, ich denke so mache ich es.
    Trotzdem würde ich gerne verstehen, wieso das System wie ich es im Ausgangspost beschrieben habe zu keiner Endlosschleife führt. Sowohl mit als auch ohne & müsste das passieren, nur das ohne & zusätzlich noch der Speicher vollgeschrieben wird weil jedesmal ein neues Objekt erzeugt wird.
    Kann mir das jemand erklären?

    Ach und ansonsten kann ich nur sagen: Habe jetzt in der Zwischenzeit mit new B(&$this) gearbeitet und bisher funktioniert das sehr gut. Wüsste gerne was da genau bei PHP passiert und wieso / wieso nicht man das verwenden sollte?
    Das $this eine spezielle Variable ist stimmt zwar, aber im Grunde enthält sie ja nur die Instanz des Objekts innerhalb der Klasse, also kann ich sie doch prinzipiell auch referenzieren und weitergeben.

    Bisschen Aufklärung bei dem Thema wär toll

    mfg

    Einen Kommentar schreiben:


  • nikosch
    antwortet
    Code gut? Code schlecht?
    Kommt drauf an. Das & kannste bei php5 weglassen.

    Was auch ginge, wäre ein statisches Array in A, das die Instanzen über einen Schlüssel verwaltet.

    Bspw.
    PHP-Code:
    class {
      private static 
    $instances;

      public 
    $value NULL;
      public 
    $fields = array();
      
      public static 
    getInstance ($key)
        {
        return (
    self::$instances[$key]);
        }

      public function 
    __construct($value
        {
        
    $this->key md5(rand ()); // Bsp. Geht sicher besser
        
    self::$instances[$key] = $this;

        
    $this->value $value;
        
    $this->fields[] = new B($this->key);
        }

    }

    class 
    {
      public function 
    __construct($key) {
        
    $object A::getInstance  ($key);
        
    $object->whatever ();
        
    //Hier muss ich auf $value von A zugreifen können
      
    }

    Natürlich kannst Du die Instanzen auch in einer Registry oder sonsteinem globalen Objekt verwalten. Aber so find ichs schon ganz elegant.

    Einen Kommentar schreiben:

Lädt...
X