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

  • 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


  • #2
    PHP-Code:
    $this->fields[] = new B(&$this); 
    würde ich nicht tun, wird zu fehlern führen.
    PHP-Code:
    Nun kenne ich mich mit Referenzen zu Objekten leider nicht so gut ausIch 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. 
    hm??? Wegen der Referenz? Nein, du machst damit nur dass beide auf denselben Platz im Arbeitsspeicher zugreifen, dh wenn A was ändert ist es bei B auch so und umgekehrt. Der Variable existiert im speicher nur einmal.

    Trotzdem : $this ist ein spezieller Wert, nicht als Referenz übergeben!


    PHP-Code:
    $instanzA= new A;

     
    // nun könntest du rein theorethisch als referenz übergeben, oder du verwendest globale Variablen 
    PHP-Code:
    class A{
      public 
    $value NULL
      public 
    $instanzB;
       
      public function 
    __construct($value) { 
        
    $this->value $value
        
    $this->instanzB = new B(); 
      }
    }

    class 

      public function 
    __construct() { 
       echo 
    $GLOBALS['instanzA']->value;  //sollte nun value von der Klasse A sein
       
      

    Kommentar


    • #3
      Zitat von Salkin Beitrag anzeigen
      PHP-Code:
      $this->fields[] = new B(&$this); 
      würde ich nicht tun, wird zu fehlern führen.

      hm??? Wegen der Referenz? Nein, du machst damit nur dass beide auf denselben Platz im Arbeitsspeicher zugreifen, dh wenn A was ändert ist es bei B auch so und umgekehrt. Der Variable existiert im speicher nur einmal.

      Trotzdem : $this ist ein spezieller Wert, nicht als Referenz übergeben!


      PHP-Code:
      $instanzA= new A;

       
      // nun könntest du rein theorethisch als referenz übergeben, oder du verwendest globale Variablen 
      PHP-Code:
      class A{
        public 
      $value NULL
        public 
      $instanzB;
         
        public function 
      __construct($value) { 
          
      $this->value $value
          
      $this->instanzB = new B(); 
        }
      }

      class 

        public function 
      __construct() { 
         echo 
      $GLOBALS['instanzA']->value;  //sollte nun value von der Klasse A sein
         
        

      Danke für die Antwort.
      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 ...

      Zu deiner Lösung: Die kann ich leider nicht nehmen da der Variablenname von der Instanz von A nicht fest ist.
      B ist eigentlich nur eine "Hilfsklasse" von A. Im Klartext: A ist eine Klasse "HTMLForm" die mir HTML-Formulare einfach und valide erzeugen soll. B ist hier "HTMLFormField", also ein Feld innerhalb es Formulars. Allerdings brauche ich in HTMLFormField einigige Informationen aus dem Formular, zu dem das Feld gehört - und genau darum gehts dann im Endeffekt.

      mfg

      Kommentar


      • #4
        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.
        Refining Linux: “Performing Push Backups – Part 1: rdiff-backup

        Kommentar


        • #5
          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.
          --

          „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
          Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


          --

          Kommentar


          • #6
            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

            Kommentar


            • #7
              Nein, nicht falscher Thread. Nur frage ich mich, wo das Problem liegt, wenn die Eigenschaften doch eh public sind 8was eigentlich nicht sein sollte).
              Refining Linux: “Performing Push Backups – Part 1: rdiff-backup

              Kommentar


              • #8
                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

                Kommentar


                • #9
                  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)...
                  --

                  „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                  Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                  --

                  Kommentar


                  • #10
                    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.
                    Refining Linux: “Performing Push Backups – Part 1: rdiff-backup

                    Kommentar


                    • #11
                      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.

                      Kommentar


                      • #12
                        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

                        Kommentar


                        • #13
                          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.
                          --

                          „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                          Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                          --

                          Kommentar


                          • #14
                            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.
                            Refining Linux: “Performing Push Backups – Part 1: rdiff-backup

                            Kommentar


                            • #15
                              da in PHP generell Referenzen auf Objekte übergeben werden
                              Seit PHP5.
                              --

                              „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                              Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                              --

                              Kommentar

                              Lädt...
                              X