[PHP5] kleine Frage zum includieren..

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

  • [PHP5] kleine Frage zum includieren..

    Nabend alle zusammen,

    Ich habe in einem beliebigen Verzeichnis beliebig viele PHPs, in denen ich derzeit zum Test verschiedene Objekte initialisiere bzw. deklariere.
    Diese Dateien sollen automatisch in mein System includiert und somit ausgeführt werden. ( also die Scripte darin )

    Nun hab ich zum Test ein statisches include ausgeführt...
    PHP-Code:
    include( "verzeichnis/init.php" ); 
    .. dies funktioniert wunderbar. Er führt alles aus, was ich will und ich hab im weiteren Code Zugriff auf die erzeugten Objekte.

    Nun möchte ich sämtliche Dateien in diesem verzeichnis bzw. dessen unterordner und deren *.phps automatisch includieren.
    Dafür habe ich eine Funktion geschrieben, die das erledigt. Sie funktioniert sogar tatellos... Ich habe zum Test mal in jede der PHPs ein Echo gelegt um zu sehen, ob er alles findet und ausführt.
    Das komische ist nun, dass er zwar die dateien finden und die Echos ausgibt aber meine Objekte werden nicht initialisiert.

    Woher kann das kommen?
    Die Funktion, die alles includiert schaut so aus:
    PHP-Code:
    function include_dir_php$folder )
    {
        
    $handle  realpath$folder );
        if (
    $handle == false){

            echo 
    "Der Pfad: \"<b>".$folder."</b>\" existiert nicht<br>";

        }else{
        
            
    $handle opendir $handle ); 
            while (
    $file readdir ($handle))
            {
                
    // Dateindung herausfinden
                
    $dateiendung pathinfo$file );
                
    $dateiendung $dateiendung["extension"] ;
                        
                if ( 
    is_dir(realpath($folder)."/".$file) && $file != "." && $file != ".." ){                    

                    
    include_dir_phprealpath$folder )."/".$file );                

                }
                            
                if (
    $dateiendung == "php" ){    

                    
    //require_once ( realpath($folder)."/".$file );                
                    
    include ( realpath($folder)."/".$file );

                }

            }

        }


    Mario

  • #2
    Re: [PHP5] kleine Frage zum includieren..

    Original geschrieben von GELight
    Das komische ist nun, dass er zwar die dateien finden und die Echos ausgibt aber meine Objekte werden nicht initialisiert.
    welche objekte, wo sollen diese erzeugt werden?

    Kommentar


    • #3
      meinst du soetwas?

      b.php
      PHP-Code:
      $foo = new FooClass(); 
      a.php
      PHP-Code:
      function incl(){ include 'b.php'; }

      incl();
      echo 
      $foo->some_method(); 
      selbstverständlich ist $foo außerhalb von incl() nicht bekannt.

      Kommentar


      • #4
        [PHP5] include

        Aber natürlich.... du hast ja Recht... hmmm.
        Das hatte ich ja voll vegessen in meinem Schreibwahn..
        Ist ja innerhalb der Funktion alles.

        Hmm, wie könnte ich denn sonst mein verzeichnis auslesen lassen, die Objekte initialisieren und nach außen hin freigeben?

        Ich könnte es statisch includieren aber dann müsste ich meine Klassenaufrufe alle in eine Datei legen und das kann auf Dauer sehr viel werden...

        Mario

        Kommentar


        • #5
          Eine mögliche Lösung ist beispielsweise:
          PHP-Code:
          $GLOBALS['obj'] = new classname(); 
          Das würde das Problem des Gültigkeitsbereichs umgehen...
          Nieder mit der Camel Case-Konvention

          Kommentar


          • #6
            verzichte doch einfach auf die funktionsdeklaration (mit anderen worten, baue den code block einfach an der stelle ein, an der du die includes brauchst; ganz ganz häßlich solches massen-inkludieren...)

            Kommentar


            • #7
              [PHP5] include

              @Griecherus,

              Dann müsste ich später immer über $GLOBALS['obj'] auf mein Object zugreifen richtig? Hmm... Dazu ist doch ein "umgehen" immer nicht wirklich schön oder?

              @penizillin,

              Gerade das statische in den Code einbauen wollte ich irgendwie vermeiden, da ich sowas alles möglichst dynamisch halten möchte.
              Mit anderen Worten: das System soll das alles im Hintergrund erledigen, sodass ich da nichts mehr anrühren brauche.

              Aber was spricht denn gegen ein automatisches includieren?
              Ob ich 20x untereinander include( "xyz.php" ); stehen habe oder das ganze über eine Funktion löse ist doch in dem Fall egal oder nicht?

              Mario

              Kommentar


              • #8
                GELight, habe immer noch nicht so richtig verstanden, was du da vorhast.

                wenn's dir aber um dynamischen include für klassen-deklaration geht, kannst du auch __autoload() benutzen.

                Kommentar


                • #9
                  [PHP5] include

                  Hallo 3DMax,

                  Ich möchte eigentlich genau das machen, was penizillin in seiner ersten Antwort so schön veranschaulicht hat.
                  In einem Verzeichnis liegen PHPs, in denen ich nur die initialisierung und/oder auch die deklarierungen zu einem erstellten Objekt stehen habe.

                  Und dieses Verzeichnis möchte ich dynamisch durchlaufen und sämtliche Klassen bzw. Objekte erstellen lassen, da ich später damit arbeiten möchte. Das ganze aber möglichst dynamisch alles, da ich nicht immer das includieren statisch per hand schreiben will.

                  Es soll sozusagen an einer Stelle im System Dateien geben, in der ich meine Objecte erstellen lasse... an ander ganz anderen Stelle will ich mit diesen arbeiten.

                  Ich wüsste nicht, wie ich es jetzt noch genauer beschreiben kann, was ich machen will.

                  Mario

                  Kommentar


                  • #10
                    Lies dir das mal durch zum Thema autoload.
                    Nieder mit der Camel Case-Konvention

                    Kommentar


                    • #11
                      [PHP5] include

                      Hab das eben schon gelesen als es 3DMax gepostet hatte.
                      Ich werd mir das wohl nochmal durch den Kopf gehen lassen alles.

                      Wobei meineigentliches Problem ja nicht das aufrufen einer nicht existirenden Klasse ist. Okay.. klar es kommt natürlich genau zu diesem Fehler bzw. dieser Situation, dass meine Klassen oder bzw. Objekte noch nicht vorhanden sind, wenn ich versuche darauf zuzugreifen. Da ich meine Deklerationen am Objekt auch in diesen Dateien machen möchte, geht das nicht mit dieser Funktion.
                      Diese ruft ja einfach nur eine PHP auf, die den selben Namen wie die Klasse selbst hat, haben muss und führt die Klasse aus.

                      Ich habe aber völlig verschiedene Konstruktoren. Die eine Klasse braucht oder verlangt nach einem Parameter im Konstruktor... die nächste nicht.. die dritte wieder mehrere usw...

                      Ich verstehe die Funktionsweise dieser kleinen... ich sag mal... Hilfsfunktion von PHP aber gefallen tuts mir nicht.

                      Wenn, dann möchte ich schon sicherstellen, dass die komplette Datenverarbeitung vorher stattfindet... sprich: aufrufen der PHPs... ausführen meiner Klassen und dann erst gehts weiter zur zB. Ausgabe von allem.

                      Ich hoffe ihr könnt mir folgen. Ich denke aber schon oder?

                      Mario

                      Kommentar


                      • #12
                        Re: [PHP5] include

                        Original geschrieben von GELight
                        Hab das eben schon gelesen als es 3DMax gepostet hatte.
                        Ich werd mir das wohl nochmal durch den Kopf gehen lassen alles.

                        Wobei meineigentliches Problem ja nicht das aufrufen einer nicht existirenden Klasse ist. Okay.. klar es kommt natürlich genau zu diesem Fehler bzw. dieser Situation, dass meine Klassen oder bzw. Objekte noch nicht vorhanden sind, wenn ich versuche darauf zuzugreifen. Da ich meine Deklerationen am Objekt auch in diesen Dateien machen möchte, geht das nicht mit dieser Funktion.
                        Diese ruft ja einfach nur eine PHP auf, die den selben Namen wie die Klasse selbst hat, haben muss und führt die Klasse aus.

                        Ich habe aber völlig verschiedene Konstruktoren. Die eine Klasse braucht oder verlangt nach einem Parameter im Konstruktor... die nächste nicht.. die dritte wieder mehrere usw...

                        Ich hoffe ihr könnt mir folgen. Ich denke aber schon oder?

                        Mario
                        Ich glaube da hast du etwas falsch verstanden. Dass du Konstruktoren hast, die natürlich voneinander abweichen können, was zu übergebende Parameter angeht, krazt Autoloading reichlich wenig. Was __autoload tut, ist Folgendes:
                        PHP-Code:

                        // a.class.php
                        class a
                        {
                            public function 
                        __construct($test_param)
                            {
                                echo 
                        $test_param// nur zum testzweck
                            
                        }
                        }

                        // irgendeine andere datei

                        function __autoload($classname)
                        {
                            require_once 
                        $classname '.class.php';
                        }

                        $obj = new a('ich bin ein parameter, der dem konstruktor uebergeben wird'); 
                        __autoload wird automatisch aufgerufen, sobald du versuchst, eine Klasse (in diesem Fall die Klasse a) zu benutzen, die noch nicht instanziiert wurde - und versucht, diese zu laden (siehe Funktion). Wie viele Parameter du welcher Klasse übergibst, ist dabei belanglos. Du wirst, was das angeht, also nicht eingeschränkt.
                        Das müsste eigentlich genau das sein, wonach du suchst.
                        Zuletzt geändert von Griecherus; 12.12.2006, 02:38.
                        Nieder mit der Camel Case-Konvention

                        Kommentar


                        • #13
                          [PHP5] include

                          Hmm... also danke nochmal für die Erklährung. Das ist schon ganz interessant so. Ich denke, dass ich die Funktion ansich jetzt schon verstanden habe.

                          Einen kleinen Unterschied habe ich aber dennoch, wenn ich mir das so anschaue. Die __autoload ruft doch meine Klasse auf, wenn diese noch nicht initialisiert ist oder? Ich möchte aber direkt danach bestimmte Parameter in der Klasse über weitere Methoden setzen lassen.
                          Das bedeutet ich will nicht nur über __autoload förmlich den Konstruktor ausführen lassen....

                          Moment.. ich zeig euch nochmal am besten meinen Aufbau, wie ich ihn habe und wie ich mir das vorgestellt habe. Wie gesagt... mit der statischen includierung funktionierts ja.... das Problem derzeit lag ja eigentlich nur daran, dass meine Objecte nur in der Funktion erreichbar waren, wie penizillin schon geschrieben hatte.

                          ROOT Verzeichnis: cms.php
                          In der cms.php führe ich in dem Fall 2 Aktionen aus.

                          1. includieren aller Dateien aus dem INIT verzeichnis und ausführen der Codes...
                          2. Ausführen und darstellen des Templates vom CMS. ( das steht alles schon... ich brauch hier dann halt den zugriff auf die Klassen.
                          Als Beispiel könnte in den kommenden Dateien irgendwo ein:
                          PHP-Code:
                          $tab1->show(); 
                          ... stehen, welches ja nur noch eine Methode der Klasse ausführt.
                          Ich will also hier nicht erst die Klasse aufrufen.

                          INIT Verzeichnis mit allen PHPs und den Klassenaufrufen.
                          dies hier wäre ein Beispiel, was dort drin stehen kann:
                          PHP-Code:
                              $tab1 = new tab"tabnane1" );
                              
                          $tab1->set_content_style"padding: 20px;" );
                              
                          $tab1->set_skin$skin );
                              
                          $tab1->add_reiter"Ansicht""administration/admin_test3.php"$skin."cms_dir_open.gif"false );
                              
                          $tab1->add_reiter"Bearbeiten 1""administration/admin_test1.php"$skin."cms_file_root.gif"true );
                              
                          $tab1->add_reiter"Files""administration/admin_test1.php"$skin."cms_cut.gif"false );
                              
                          $tab1->add_reiter"Optioinen""administration/admin_test2.php"$skin."admin_edit.gif"false );
                              
                          $tab1->add_reiter"Downloads"""$skin."cms_download.gif"false );
                              
                          $tab1->add_reiter"Help"""$skin."cms_help.gif"false ); 
                          ...Hier sollen also die Klassen ausgeführt werden UND bestimmte Parameter dafür gesetzt werden.

                          Ich will sozusagen einfach nur die möglichst absolute Trennung zwischen dem initialisieren + vergabe der Eigenschaften und der Darstellung schaffen.
                          Daher möchte ich in meinen reinen Admindateien im Normalfall nichts vonwegen $test = new test(); stehen haben... das soll alles schön getrennt passieren. ( vergessen wir hier einfach mal verschachtelte Klassen ). Erstmal nur das hier.... und gehen muss es oder etwa nicht? Oder bin ich etwa immernoch auf dem totalen Holzweg?

                          Mario

                          Kommentar


                          • #14
                            Um ehrlich zu sein erkenne ich da keinen Grund, kein __autoload zu benutzen. Ich glaube ich kann nicht nachvollziehen, wieso man die Initialisierung einer Klasse unbedingt strikt von jeglichen Methodenaufrufen trennen möchte, aber das liegt natürlich bei dir. Schließt du autoloading aus, bleiben eigentlich nur die - bereits erwähnten - Möglichkeiten $GLOBALS zu benutzen oder die Klassen entweder statisch zusammen oder einzeln genau dort zu includen, wo du sie brauchst - und das dürfte für dich ja eigentlich entfallen.
                            Die "saubersten" Lösungen sind leider genau die, die du ausschließt.
                            Zuletzt geändert von Griecherus; 12.12.2006, 14:08.
                            Nieder mit der Camel Case-Konvention

                            Kommentar


                            • #15
                              Hi,
                              ich halte es für keine gute lösung aber man könnte folgendes machen.
                              Du gehst in etwa den weg den man auch mit shared libs geht.
                              Jedes deiner init-scripte tut was es tun muss initialisiert die klasse und
                              gibt dann das objekt über eine einheitliche init-funktion zurück. Das wäre
                              ein äquivalent zum sharelib einsprungpunkt. Als einfache konvention könnte
                              die funktion dateiname_init() heissen. Dann packst du das laden der
                              ganzen geschichte in eine klasse, damit du das GLOBALS-problem los wirst.
                              Dann noch eine convenience-methode um an die objekt zu kommen
                              und du kannst relativ schmerzfrei arbeiten.

                              Das könnte folgendermaßen aussehen.
                              Nehmen wir an du hast folgende init-dateien im verzeichnis '/home/user/init'

                              foo.php
                              PHP-Code:
                              class Foo{
                                 private 
                              $val_;
                                 public function 
                              __construct($val){
                                      
                              $this->val_ $val;
                                 }
                                public function 
                              inspect(){
                                    return 
                              $this->val_;
                                }
                              }

                              function 
                              foo_init(){
                                 return new 
                              Foo('foo');

                              bar.php
                              PHP-Code:
                              class Bar{
                                 private 
                              $val_;
                                 public function 
                              __construct($val){
                                      
                              $this->val_ $val;
                                 }
                                public function 
                              inspect(){
                                    return 
                              $this->val_;
                                }
                              }

                              function 
                              bar_init(){
                                 return new 
                              Bar('bar');

                              Dann könnte der rest so aussehen:
                              PHP-Code:
                              <?php

                              error_reporting
                              (E_ALL);

                              interface 
                              Visitor{
                                public function 
                              visit($obj);
                              }
                              interface 
                              Visitable{
                                public function 
                              accept(Visitor $obj);
                              }

                              class 
                              LibFile implements Visitable{
                                  private 
                              $path_;
                                  private 
                              $init_func_;
                                  private 
                              $class_name_;
                                  
                                  public function 
                              __construct($path_str,$suffix){
                                  
                              $this->path_ $path_str;
                                  
                              $fname basename($this->path_);
                                  if(!
                              $this->ends_with($fname,'.php'))
                                    throw new 
                              Exception('missmatch');
                                  
                              $this->class_name_ strtolower(substr($fname,0,strlen($fname) - 4));
                                  
                              $this->init_func_ $this->class_name_.$suffix;
                                  }
                                  
                                  public function 
                              accept(Visitor $visitor){
                                    
                              $visitor->visit($this);
                                  }
                                  
                                  public function 
                              file_name(){
                                    return 
                              $this->path_;
                                  }

                                  public function 
                              init_func(){
                                    return 
                              $this->init_func_;
                                  }

                                  public function 
                              class_name(){
                                    return 
                              $this->class_name_;
                                  }

                                  protected function 
                              ends_with($what,$with){
                                    return 
                              substr($what,strlen($what) - strlen($with)) == $with true false;
                                  }
                              }

                              class 
                              SLibLoader implements Visitor{
                                  private 
                              $target_;
                                  public function 
                              __construct($target){
                                      
                              $this->target_ $target;
                                  }
                                  public function 
                              visit($file){
                                      require_once(
                              $file->file_name());
                                      
                              $this->target_->add($file->class_name(),call_user_func($file->init_func()));
                                  }
                              }

                              class 
                              CMSEnv{
                                  private 
                              $instances_;
                                  private 
                              $visitor_;
                                  public function 
                              __construct($dir,$init_suffix '_init'){
                                   
                              $this->instances_ = array();
                                   
                              $this->visitor_ = new SlibLoader($this);
                                   
                              $this->include_slibs(realpath($dir),$init_suffix);
                                  }

                                  public function 
                              add($name,$obj){
                                    
                              $this->instances_[$name] = $obj;
                                  }

                                  protected function 
                              include_slibs($the_dir,$suffix){
                                  
                              $d dir($the_dir);
                                  while(
                              false !== ($cur $d->read())){
                                    if(
                              $cur !== '.' && $cur !== '..' && is_dir($the_dir.'/'.$cur)){
                                        
                              $this->include_slibs($the_dir.$cur.'/',$suffix);
                                    }else{
                                      try{
                                      
                              $lib = new LibFile($the_dir.'/'.$cur,$suffix);
                                      
                              $lib->accept($this->visitor_);
                                      }catch(
                              Exception $ex){
                                      
                              //file did not match
                                      //just go on
                                      
                              }
                                    }
                                  }
                                  }

                                  public function 
                              __get($name){
                                  if(!isset(
                              $this->instances_[$name]))
                                    return 
                              null;
                                  return 
                              $this->instances_[$name];
                                  }
                              }
                              Das ganze genutzt via:
                              PHP-Code:
                              $cms = new CMSEnv('/home/user/init/');
                              print 
                              $cms->foo->inspect()."\n";
                              print 
                              $cms->bar->inspect()."\n"
                              Ausgabe:
                              Code:
                              foo
                              bar
                              HTH

                              greets
                              Zuletzt geändert von closure; 12.12.2006, 15:57.
                              (((call/cc call/cc) (lambda (x) x)) "Scheme just rocks! and Ruby is magic!")

                              Kommentar

                              Lädt...
                              X