Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Magic functions und die dynamische Eigenschaftsbefüllung...

Einklappen

Neue Werbung 2019

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

  • [Erledigt] Magic functions und die dynamische Eigenschaftsbefüllung...

    Hi,

    ich hab zur Zeit ein Problem mit einer Singlton... ich kann das Problem jetzt gerade nicht so ganz in Worte fassen, deshalb gibts gleich einen Beispielcode von mir:

    PHP-Code:
    <?php
        
    /** normaler container - keine singlton, nur eine Beispielklasse */
        
    class container {
            private 
    $container = array();
            
            function 
    __set($name$value) {
                
    $this->container[$name] = $value;
            }

            function 
    __get($name) {
                return 
    $this->container[$name];
            }
        }

        
    $c = new container;

        
    // das klappt ohne Probleme, der Wert steht in der Eigenschaft $container
        
    $c->test "yeah";

        
    // was ich jetzt versuchen möchte ist, den Namen der dynamisch
        // hinzugefügten Variable in eine andere Variable schreiben
        
    $hm "variable";
        
    $c->$hm = array();
        
    $c->$hm['test'] = "wert";
        
    // ausgeschrieben sollte das dann so aussehen:
        // $c->variable = array();
        // $c->variable['test'] = "wert";
        
        
    var_dump($c);
        
    // allerdings wird aus dem ganzen dann ein $container = array('test' => 'yeah', 'v' => 'wert');
    ?>
    Wisst ihr was ich mein bzw wie ich das erreichen kann?
    LG

  • #2
    Du musst schon mal eine Problemstellung liefern was du eigentlich erreichen willst. Mache dir doch bitte vorher Gedanken darüber, ein ich habe ein Problem aber weiß selber nicht welches Gedöns ist für keinen hier verwertbar.

    Zu deinem Code, dass sieht sieht sehr merkwürdig aus, was immer du auch vorhast beschreieb es genau.
    Aber du weißt schon zu was __set() und __get() da sind und wofür sie Gedacht sind und was sie sind wenn du sie angelegt hast oder=

    Gruß der Litter

    Kommentar


    • #3
      Du suchst:
      PHP-Code:
      $c->{$hm}['test'
      wobei das nur funktioniert, sofern __get() ne Referenz zurück gibt - andernfalls wird Dir PHP in einer Notice mitteilen, dass indirekte Modifikationen nicht funktionieren.

      Gruß Jens

      Kommentar


      • #4
        Für solche Fälle nutzt man eigentlich auch keine __set() und __get() Methoden, eher sollte man da auf eine eigengeschriebene set und get Methode zurückgreifen oder eine add Methode und das ganze als ein Fluentinterface.

        Kommentar


        • #5
          $hm = "variable";
          $c->$hm = array();
          $c->$hm['test'] = "wert";
          Ist auch sehr speziell um nicht zu sagen: unübersichtlich. Und oh Wunder, mit Array hättest Du ähnliche Probleme. Ist auch kein Wunder, denn $$hm (was dem Beispiel etwa entspricht) aufzulösen, wenn man nicht weiß, ob der nachfolgende Index zu $hm oder dem Gesamtkonstrukt gehört, dürfte den Interpreter vor eine echte Herausforderung stellen:

          $ von $hm['test'] vs. Index ['test'] von $$hm

          Wozu willst Du denn sowas umsetzen?

          Kommentar


          • #6
            Sorry Leute, ich hätt den Post wirklich erst jetzt verfassen sollen, wo ich alles beisammen habe.

            Also meine Singleton sieht wie folgt aus:
            PHP-Code:
            <?php
                
            final class C_MAIN_Container {
                    private static 
            $instance null;
                    
                    private 
            $container = array('tmp' => array());
                    
                    private function 
            __construct() {}
                    private function 
            __clone() {}
                    public function 
            __toString() {
                        return 
            false;
                    }
                    
                    public function 
            instance() {
                        if (
            self::$instance === null) {
                            
            self::$instance = new self;
                        }
                        
                        return 
            self::$instance;
                    }
                    
                    public function 
            __set($name$value) {
                        
            $this->container[$name] = $value;
                    }
                    
                    public function &
            __get($name) {
                        if (
            array_key_exists($name$this->container)) {
                            return 
            $this->container[$name];
                        }
                        
                        return 
            $null;
                    }
                    
            // ...
                
            }
            ?>
            Ganz normal also. Ich habe das auch mit der Referenz schon eingebunden gehabt.
            Der Container wird in mehrere Bereiche aufgeteilt. Also die Eigenschaft $container hat sozusagen Hauptbereiche:
            PHP-Code:
            array(
               
            'extensions' => array(),
               
            'controllers' => array()
               
            //....
            ); 
            Mein Problem besteht jetzt darin, dass ich eben Klassen dynamisch reinlade.

            Beispielsweise schreib ich folgende Zeilen:
            PHP-Code:
            loadClass('foo'); 
            Die loadClass-Funktion ist in etwa wie folgt aufgebaut:
            PHP-Code:
            function loadClass($name$extend='bereich') {
               
            $file $name.'.php';

               
            // überprüfung ob datei existiert und ob es noch im erlaubten bereich gespeichert ist
               // ...

               
            $class ucwords($name);

               
            // Im Normalfall schreib ich jetzt die Variablen in den Container

               // Datei laden und überprüfungen anstellen
               
            require_once $file;
               
            // ... existiert Klasse...
               
               // Die Funktion instance gibt mir den Container zurück.
               // also ...
               // * $extend beinhaltet den Bereich, die virtuelle Eigenschaft des Containers
               // * $name beinhaltet den Namen, als was die Klasse im Bereich geladen wird
               // * $class beinhaltet eben den Klassennamen
               
            instance()->$$extend[$name] = new $class;
               
               
            // überprüfen ob die Methode init existiert und dann ausführen...
               
            instance()->$$extend[$name]->init();

            Ich glaub am einfachsten ist es, wenn der Container eine methode hat, die sich um das ganze kümmert. Beispielsweise
            PHP-Code:
            instance()->extend($extend, new $class); 
            War das halbwegs verständlich? Danke schonmal

            Kommentar


            • #7
              Ich glaub am einfachsten ist es, wenn der Container eine methode hat, die sich um das ganze kümmert.
              Ja. So macht man das in OOP.

              Kommentar


              • #8
                Mir ist dein Klassenkonstrukt irgendwie zu virtuell ..

                Zitat von Lumio Beitrag anzeigen
                Wisst ihr was ich mein bzw wie ich das erreichen kann?
                LG
                Wenn die Frage immer noch offen ist .. mit $c->__set($variable, $value) kannst du auch variable Variablen setzen.

                Halte allerdings absolut garnichts von __set und __get. Das erspart anfangs Tipparbeit, entfaltet sich allerdings zum Zeitkiller, sobald das Projekt mal wieder angefasst werden muss.

                Kommentar


                • #9
                  Ja naja, ich lade ja die gebrauchten Klassen in unterschiedlichen Bereichen. Insofern macht es meiner Meinung nach schon Sinn.

                  Aber Danke fürs zu hören und helfen Ich machs jetz mit der extend Variante

                  Kommentar


                  • #10
                    Obligatorische Anmerkung, dass Singletons ungünstig sind, weil sie Abhängigkeiten verdecken und Unit-Testing erschweren.

                    - http://misko.hevery.com/code-reviewers-guide/ (vor allem wohl Flaw #3)

                    Kommentar


                    • #11
                      Hm... gibts da ne Alternative bzw irgendwo was wo man sich einlesen könnte

                      Dennoch danke

                      Kommentar


                      • #12
                        Generell ist Dependency Injection die Alternative. Das bedeutet im Prinzip, dass du einer Klasse diejenigen Abhängigkeiten, die sie benötigt, von außen zuweist. Etwa per Konstruktor.

                        PHP-Code:
                        $dbAdapter = new DBAdapter();
                        $myController = new Controller($dbAdapter);
                            
                        // alternativ z. B. auch per Setter ($myController->setDbAdapter()) 
                        So ist klar erkennbar, mit welchen Klassen ein Objekt interagiert, wohingegen du bei dem Singleton/Repository-Ansatz den gesamten Code durchgehen musst, um die konkreten Abhängigkeiten zu erkennen, da ja überall $obj = MyContainer::getInstance()->get('MyClassName'); stehen könnte.

                        Das ist hier alles besser erklärt: http://misko.hevery.com/code-reviewe...te-singletons/

                        Was deinen Class Loader angeht, schau dir mal spl_autoload_register an. Da gibt es einige nette Lösungen, sowas zu automatisieren, wenn die Verzeichnisstruktur einem bestimmten Schema folgt.

                        Kommentar


                        • #13
                          PS. __toString() muß immer einen string zurückgeben. (sonst würde es ja __toBoolean() heißen …)

                          Kommentar

                          Lädt...
                          X