Ankündigung

Einklappen
Keine Ankündigung bisher.

Include über Verzeichnisse unterschiedlicher Tiefe

Einklappen

Neue Werbung 2019

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

  • Include über Verzeichnisse unterschiedlicher Tiefe

    Huhu

    ich les' hier schon seit einiger Zeit mit und hab bisher auch immer alles schön gefunden, was ich suchte - bin so groß geworden! :P

    Aber eine Frage, oder ein Problem viel mehr blieb bestehen, mit dem ich mich schon ewig rumplage:
    includen von PHP-Dateien über mehrere Ebenen. Sprich ich hab:
    1) <root>/nira_config.php
    2) <root>/nira_install/nira_csql.php
    3) <root>/nira_glob/functions/function.php
    4) <root>/nira_glob/classes/class.php

    In der nira_config.php (1) steht ein Mehrdimensionales Array mit diversen Configurationen/Settings und solch kram, der Zentrale Sammlpunkt eben.

    In (2) nira_csql.php wird
    PHP-Code:
    <?php include("../nira_config.php"); ?>
    die Config-Datei (1) included.
    Dies funktioniert ja auch soweit, da die zwei Punkte ja sagen, geh eine Ebene höher.

    Include ich jetzt jedoch mit Datei (3) oder (4) die config:
    PHP-Code:
    <?php include("../../nira_config.php"); ?>
    funktioniert dies zwar, aber sobald ich in der config-Datei (1) selbst auch ein include Einbaue (z.B. um User-Eingaben in der Configdatei zu trimmen, escapen, whatever, o.ä.), welches sich auf das selbe Verzeichnis wie die Config-Datei bezieht (sprich: "./nira_edit_cfg.php"), wird diese Pfadanweisung (aus nachvollziehbaren Gründen) nicht im <root> durchgeführt, sondern in den Unterordnern.

    Wie bringe ich es nun zustande, dass ich das im letzten Absatz beschriebenen Problems umgehen kann?

    Sicher, ich könnte die System-Variable dazu missbrauchen - allerdings habe ich dort das Problem, dass ich diese - ich nenn es mal "Standardstruktur" für andere Projekte nicht verwenden kann, ohne die Systemvariable anzupassen.
    $_system['DOCROOT'] (oder so ähnlich) zeigt ja nur auf das tatsächliche root, nicht jedoch auf das "scheinroot", in welcher sich jeweils die CFG-Datei befindet.

    Ich hoffe, dass ich mein Anliegen gut erklärt hab.
    Bestimmt gibts da wieder irgendwas ganz banales, was ich mal wieder übersehe!

    LG
    Nira


  • #2
    Naja wie du schon richtig erkannt hast, hast du 2 Möglichkeiten.
    1) Du referenzierst alle Dateien absolut, was lästig wird, wenn du dein Projekt umziehst.
    Code:
    /directory/project/app/nira_glob/functions/function.php etc
    2) Du erstellst dir eine bootstrap und setzt dort eine systemweitere Konstante zum root deines Projektes.
    Läuft am Ende auf das selbe (absolute Pfade) hinaus, erspart aber Arbeit, wenn sich das Verzeichnis ändert.
    PHP-Code:
    //bootstrap
    define('PROJECT_ROOT''/directory/project/app/');

    //alle anderen Dateien
    include (PROJECT_ROOT."nira_glob/functions/function.php"); 
    sigpic

    Kommentar


    • #3
      Zitat von Niranda Beitrag anzeigen
      Dies funktioniert ja auch soweit, da die zwei Punkte ja sagen, geh eine Ebene höher.
      Eine Ebene höher ist richtig. Aber von welchem Verzeichnis aus wird denn eine Ebene höher gegangen? Die Antwort lautet: vom Arbeitsverzeichnis aus. Es stellt sich dann natürlich die Frage, welches Verzeichnis das Arbeitsverzeichnis ist. Wenn du eine HTTP-Anfrage nach http://www.example.com/foo/bar/baz.php stellst, dann ist das Verzeichnis das Arbeitsverzeichnis, in dem baz.php liegt, also normalerweise <wwwroot>/foo/bar. Wenn jetzt in baz.php steht include 'functions/boom.php' und boom.php wird daraufhin ausgeführt, dann ändert sich dadurch nicht das Arbeitsverzeichnis. Stehen in boom.php also weitere include-Anweisungen, dann werden die dortigen relativen Pfadangaben immer noch relativ zu <wwwroot>/foo/bar ausgewertet, nicht relativ zu <wwwroot>/foo/bar/functions. Das Arbeitsverzeichnis wird nicht automatisch geändert, du kannst es aber manuell mit [MAN]chdir[/MAN] ändern.
      Meinungen, die ich geäußert habe, sind nicht notwendigerweise meine eigenen. Abweichungen von der deutschen Rechtschreibung unterliegen dem Urheberrecht, dürfen aber unter den Bedingungen von verwendet werden

      Kommentar


      • #4
        Auch interessant und lesenswert: Pfade in der Webentwicklung - PHP.de Wiki.

        Gruß
        http://hallophp.de

        Kommentar


        • #5
          Huhu

          Danke für Eure Antworten!
          Ich hab mich aber jetzt mal ein bisschen durchgekaut und mir eine Klasse geschrieben, die mir in dieser Thematik vollste Unterstützung liefert.
          Im Prinzip gebe ich allen Ordnern, die zu meinem Projekt gehören, ein Prefix.
          In den meisten Fällen ist das bei mir "nira_".
          Da ich das ganze schon im Script dokumentiert habe, schreib ich's hier nur kurz.

          Also ich hab das Verzeichnis
          C:/xampp/htdocs/blneu/nira_install/nira_g/nira_test.php
          und "nira_test.php" ist das unten aufgeführte Script.
          Der Scriptname ist völlig irrelevant, wichtig ist bei dem Namen allerdings der Prefix "nira_".
          Dieser wird automatisch verwendet. Alternativ kann man auch einen anderen Prefix an die Methode übergeben.

          Die Methoden bauen sich dann den kompletten Pfad nach, in der das ausführende Script liegt, also wie oben geschrieben:
          C:/xampp/htdocs/blneu/nira_install/nira_g/nira_test.php

          Dann wird der Pfad in ein Array beim / gesplittet.
          Dieses Array wird mit einer schleife von links nach rechts bearbeitet.
          Solange die einzelnen Teile nicht das übergebene Prefix (hier "nira_") haben, wird eine Pfad-Variable immer um je ein Segment erweitert.
          Somit bleibt am Ende
          C:/xampp/htdocs/blneu/
          stehen - das Projektrootverzeichnis!

          Somit bin ich in der Lage, Absolute Pfadangaben zu machen, die jedoch dynamisch - je nach Ablage - reagieren.
          In jeder Datei muss nur (entsprechend) folgender PHP-Code:
          PHP-Code:
          <?php

          include("nira_ProjectRoot.php");

          $nira_pr = new nira_ProjectRoot;
          definePROJECT_ROOT$nira_pr->getRelProjectRoot() );        #-> PROJECT_ROOT => "/blneu/"

          include( PROJECT_ROOT."nira_glob/functions/function.php" );

          ?>
          Und natürlich muss in jedem Ordner (außer bei images o.ä.) diese Klasse als Datei liegen. Simples Copy&Paste, Änderungen muss man ja nicht vornehmen, da diese den Pfad automatisch generiert.
          Vielleicht nützt es ja einigen etwas!

          LG,
          Nira

          PHP-Code:
          <?php 

          /*
           * AUTHOR:    Niranda
           * WEBSITE:    www.Niranda.net
           * MAIL:    dev AT niranda DOT net
           * 
           * DATE:    2010-09-04
           * 
           * COPYRIGHT:
           *         Free to use without editing something in this large comment.
           * 
           *         Copyright (c): Niranda.net 2010
           */


          /*
           * CLASS-DESCRIPTION
           * -----------------------------------
           *  With this class you can manage your projects with a single prefix.
           *  May you get some problems with your projectroot, because PHP only returns the webroot f.e. C:\xampp\htdocs
           *  But your project is in a another folder: C:\xampp\htdocs\blacklist\
           *  With this class you can get your projectroot!
           *  
           *  You just have to copy this class-file in all (?) your folders where you need it.
           *  The following is in this dir: C:/xampp/htdocs/blneu/nira_install/nira_g/nira_test.php
           *  
           *  METHODE                PARAMETER            RETURN                                            Description
           *  ---------------------------------------------------------------------------------------------------------
           *  getFilename()            -                nira_test.php                                    get filename from this script
           *  getFilenameLength()        -                13                                                get the length of this filename from this scriptname
           *  getRealRoot()            -                C:/xampp/htdocs                                    PHP-Var: $_SERVER['DOCUMENT_ROOT']
           *  getRealRelPath()        -                /blneu/nira_install/nira_g/                        PHP-Var without filename: $_SERVER['SCRIPT_NAME']
           *  getRealAbsPath()        -                C:/xampp/htdocs/blneu/nira_install/nira_g/        Both above this line merged
           *  getPrefix()                -                nira_                                            Prefix from filename (nira_test.php) - explored by _
           *  getRelProjectRoot()    $prefix [string]    /blneu/                                            Relative path to this project-dir
           *  getAbsProjectRoot()    $prefix [string]    C:/xampp/htdocs/blneu/                            Absolute path to this project-dir
           * 
           * Description for the both parameters (both are still the same!)
           *  You can send a costum prefix in this methodes for your projects.
           *  Or leave it blank and just use a prefix in this file name...
           *  maybe "nira_test.php" (Prefix is now: "nira_")
           *  or "myproject_test.php" (prefix is now: "myproject_")
           */

          class nira_ProjectRoot {
              var 
          $classname "nira_ProjectRoot";
              
              var 
          $exploder;
              var 
          $prefix;
              
              var 
          $rel_script_full;
              var 
          $abs_root;
              var 
          $c_file;
              
              
          ##--> Constructor
              
          public function nira_ProjectRoot($sys_scriptname false) {
                  
          $this->rel_script_full $_SERVER['SCRIPT_NAME'];            # relative path with filename and ext.
                  
          $this->abs_root $_SERVER['DOCUMENT_ROOT'];                # absolute path to root
                  
          $this->c_file 0;                                            # filenamelength
                  
                  
          $this->exploder "_";                                        # splitter for prefixsearcher
                  
          $this->prefix false;                                        # prefix for folders
                                                                              # false = get prefix by this filename and "exploder"
              
          }
              
              
          ##--> get Filename from this file
              
          public function getFilename() {
                  
          #-> Dateinamen extrahieren
                  
          $ex_rsf explode("/"$this->rel_script_full);                # rel. full path in a array
                  
          $file $ex_rsf[count($ex_rsf) - 1];                        # last value -> Filename with ext.
                  
          return $file;
              }
              
              
          ##--> Get Filenamelength
              
          public function getFilenameLength() {
                  
          $file $this->getFilename();
                  
          $len strlen($file);
                  
          $this->c_file $len;
                  return 
          $len;
              }

              
          ##--> Get absolute Rootpath
              
          public function getRealRoot() {
                  return 
          $this->abs_root;
              }
              
              
          ##--> Get relative Path to this dir
              
          public function getRealRelPath() {
                  
          $c_file $this->getFilenameLength();
                  
          $rel_dir substr($this->rel_script_full0, -$c_file);
                  return 
          $rel_dir;
              }
              
              
          ##--> Get absolute Path to this dir
              
          public function getRealAbsPath() {
                  
          $rel_dir $this->getRealRelPath();
                  
          $abs_root $this->abs_root;
                  
          $abs_dir $abs_root.$rel_dir;
                  return 
          $abs_dir;
              }
              
              
          ##--> Get Prefix from this file
              
          public function getPrefix() {
                  
          $exploder $this->exploder;
                  
          $file $this->getFilename();                        # get prefix from this filename!
                  
          $fileparts explode($exploder$file);                # f.e., Filename: "nira_dir.php"
                  
          $prefix $fileparts[0].$exploder;                    # prefix for Folders is: "nira_"
                  
                  
          return $prefix;
              }
              
              
          ##--> Get relative Projectroot
              
          public function getRelProjectRoot($prefix false) {
                  if(
          $prefix === false || $this->prefix === false) {    # if no costum-prefix is set...
                      
          $prefix $this->getPrefix();
                  }
                  
                  
          $c_pre strlen($prefix);
                  
          $fullpath $this->getRealRelPath();                # Full relative path to this file (without filename)        
                  
          $pathparts explode("/"$fullpath);
                      
                  foreach(
          $pathparts as $key => $value) {
                      if(
          strlen($value) < strlen($prefix) || substr($value0$c_pre) != $prefix) {
                          
          $relProjectPath $relProjectPath.$value."/";
                      }
                      else {
                          break;
                      }
                  }
                          
                  return 
          $relProjectPath;        
              }
              
              
          ##--> Get absolute Projectroot
              
          public function getAbsProjectRoot($prefix false) {
                  
          $abs_root $this->getRealRoot();
                  
          $rel_pro_root $this->getRelProjectRoot($prefix);    
                      
                  
          $abs_pro_root $abs_root.$rel_pro_root;
                  
                  return 
          $abs_pro_root;
              }
          }



          ##--> Description and example - activate it if you need help! ;)

          /*    // just remove the /* at the beginning - or add /* to comment all this following line

              $nira_dir = new nira_ProjectRoot;
              
              echo "
              <html>
              <head>
                  <title>Niranda's ProjectRoot-Class</title>
              </head>
              <body>
                  <h1>Niranda's ProjectRoot-Class</h1>
                  <p>The following table is an example for your project-dirs.<br>
                  You have to change the \$prefix in the constructor of this class!</p>
                  <p>May you call your \$prefix \"nira\" and the splitter between prefix and name is always a underline: \"_\"!</p>
                  <p>An example: Your PHP is there: C:/xampp/htdocs/fuu/nira_install/nira_g/script.php<br>
                  If you changed the prefix to \"nira\" and run the \"getAbsProjectRoot\"-Function, you'll get this:<br>
                  C:/xampp/htdocs/fuu/</p>
                  <p>Remember: The 'real' PHP-Root-Path is: \"C:/xampp/htdocs/\"
                  
                  <br><br><br>
                  <p><b>Test it with your directories:</b></p>
                  <table border='1'>
                      <tr>
                          <td><b>DESCRIPTION</b></td>
                          <td><b>RETURNS</b></td>
                          <td><b>CALLED FUNCTION</b></td>
                      </tr>
                      <tr>
                          <td>This filename is:</td>
                          <td>".$nira_dir->getFilename()."</td>
                          <td>getFilename()</td>
                      </tr>
                      <tr>
                          <td>The absolute root for PHP is:</td>
                          <td>".$nira_dir->getRealRoot()."</td>
                          <td>getRealRoot()</td>
                      </tr>
                      <tr>
                          <td>This is the relative dir for this script:</td>
                          <td>".$nira_dir->getRealRelPath()."</td>
                          <td>getRealRelPath()</td>
                      </tr>
                      <tr>
                          <td>This is the absolute dir for this script:</td>
                          <td>".$nira_dir->getRealAbsPath()."</td>
                          <td>getRealAbsPath()</td>
                      </tr>
                      <tr>
                          <td>relative projectroot:</td>
                          <td>".$nira_dir->getRelProjectRoot()."</td>
                          <td>getRelProjectRoot()</td>
                      </tr>
                      <tr>
                          <td>Absolute projectroot:</td>
                          <td>".$nira_dir->getAbsProjectRoot()."</td>
                          <td>getAbsProjectRoot()</td>
                      </tr>
                  </table>
              </body>
              </html>
              ";
          /*
           * 
           */



          ?>

          Kommentar


          • #6
            Das hat sicher viel Arbeit gemacht. Und ich erinnere mich, mal etwas ähnliches geschrieben zu haben. Auch Chriz hat dazu mal Ausführungen gemacht (weiß jetzt nicht, ob das in einem anderen Zusammenhang war). Aber ehrlich gesagt - ich benutze letztendlich jetzt genau die define-Variante. Deshalb mein guter Rat: Halte das System so einfach wie möglich. Gerade in einer großen Klassensammlung gibt es viele Includes und für jede Instanz ein Objektaufruf? Auch scheint mir das System nicht komplett fehlersicher zu sein.

            [WIKI]KISS-Prinzip[/WIKI]

            Das schöne ist, dass Du in defines andere Konstanten benutzen kannst:

            index.php
            PHP-Code:
            <?php
            define 
            ('nira_DIR_ROOT_ABS' 'your/server/path/here/');

            require (
            nira_DIR_ROOT_ABS 'subpath/to/config/mainconfig.php');


            require (
            nira_DIR_LIB_ABS 'core_module.php'); 
            require (
            nira_DIR_LIB_ABS 'session_module.php'); 
            ...
            mainconfig.php
            PHP-Code:
            <?php
            define 
            ('nira_DIR_LIBRARY_ABS'     nira_DIR_ROOT_ABS 'lib/');
            define ('nira_DIR_APPLICATION_ABS' nira_DIR_ROOT_ABS 'app/');
            Als Konvention benutze ich Pfade mit abschließenden Slash, das ist allerdings Geschmachkssache. PHP-Funktionen liefern Pfade immer ohne, ich finde das mit aber praktischer.
            --

            „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


            • #7
              Ich weiß schon, was Ihr meint
              Mich stört allerdings, dass ich entweder
              a) immer über eine Datei (index.php) gehen muss oder
              b) in jeder Datei den Code eingetragen haben muss:
              PHP-Code:
              define ('nira_DIR_ROOT_ABS' 'your/server/path/here/'); 
              Ich hab ein Grundgerüst, welches ich für andere Projecte auch nutze, die aber anders heißen.
              Somit müsste ich dann im Punkt b) alle Strings abändern - und da wird bestimmt irgendetwas vergessen, was dann wieder nervendaufreibend und Zeitbeanspruchend ist.
              Das möchte ich vermeiden.
              Werde mich aber trotzdem auch mal daran versuchen - vielleicht ist es doch besser und ich seh es bloß nicht!

              Alternativ könnte man die Klasse auch als Funktion(en) umschreiben, sollte nicht so problematisch sein, wie das Ausdenken der ganzen Klasse.
              Fehleranfällig ist es bei den Usereingaben, da keine Fehler abgefangen werden, wie z.B. doppelte Slashes oder ähnliches.

              Edit:
              Zu punkt a):
              Das finde ich immer zu unübersichtlich.
              Bei kleineren Dingen funktioniert das über eine Datei prima!
              Aber sobald man über 10 Dateien included hört der spaß auf

              Kommentar


              • #8
                Dafür muss bei Dir laut Aussage:
                In jeder Datei [..] nur (entsprechend) folgender PHP-Code:
                PHP-Code:
                <?php

                include("nira_ProjectRoot.php");

                $nira_pr = new nira_ProjectRoot;
                define( PROJECT_ROOT, $nira_pr->getRelProjectRoot() ); #-> PROJECT_ROOT => "/blneu/"

                include( PROJECT_ROOT."nira_glob/functions/function.php" );

                ?>
                Das ist jetzt besser? Zudem ist
                Und natürlich muss in jedem Ordner (außer bei images o.ä.) diese Klasse als Datei liegen.
                IMHO absolut nicht zu verantworten - fehleranfällig und nahezu unwartbar.

                Wenn Du mehrere Scripte aufrufst (kein zentrales) dann musst Du eben dort im Header immer etwas zentrales einbinden (ähnlich dem Pagecontroller-Pattern). Das geht auch relativ, ist aber fehleranfällig und das musst Du auch anpassen, wenn Du neue Objektstrukturen verwendest.
                --

                „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