heinetz: optimale Verzeichnisstruktur

Hallo Forum,

ich habe mir über die Jahre für meine PHP-Projekte eine Verzeichnisstruktur angewöhnt, die ich immer wieder verwende. Jetzt stehe ich vor der Aufgabe, an einem sehr komplexen Projekt, dass ich 2007 mal aufgebaut habe weitreichende Umbauarbeiten vorzunehmen und ich möchte die Situation nutzen, diese Verzeichnisstruktur zu hinterfragen. Gibt es soetwas, wie einen Standard oder eine Empfehlung, wie die Verzeichnisstruktur optimalerweise für PHP-Projekte aussieht? Sicher kann man das nicht völlig verallgemeinern aber vielleicht haben sich bestimmte Vorgehensweisen bewährt. Beispielsweise benutze ich seit jeher eine "config.inc.php", habe aber schon häufiger gesehen, dass sie stattdessen "config.php" heisst.

Kann jemand etwas dazu sagen?

danke für Tipps und

beste gruesse,
heinetz

  1. Gibt es soetwas, wie einen Standard oder eine Empfehlung, wie die Verzeichnisstruktur optimalerweise für PHP-Projekte aussieht?

    Gibt es meines wissens nicht - viele Frameworks geben aber eine Struktur vor, wie man die Files idealerweise ablegen sollte.

    Wenn du mit deiner Struktur zurecht kommst, arbeite damit.

    Beispielsweise benutze ich seit jeher eine "config.inc.php", habe aber schon häufiger gesehen, dass sie stattdessen "config.php" heisst.

    Oder settings.php oder setup.php oder localconf.php oder LocalSettings.php ...

    1. Gibt es soetwas, wie einen Standard oder eine Empfehlung, wie die Verzeichnisstruktur optimalerweise für PHP-Projekte aussieht?

      Wenn du mit deiner Struktur zurecht kommst, arbeite damit.

      Ich komme damit zurecht, weil ich sie gewohnt bin und weiss, wo ich was finde. Vieles gewachsene halte ich aber leider mittlerweile nicht mehr für sinnvoll und würde es gerne ändern und mir dazu vorher mal anschau'n wie es andere machen.

      gruesse,
      heinetz

      1. hi,

        [..]Vieles gewachsene halte ich aber leider mittlerweile nicht mehr für sinnvoll

        ich auch nicht, eine virtuelle, fürs Web sichtbare Verzeichnisstruktur auf Dateiebene abzubilden erachte ich als nicht (mehr) sinnvoll. Zumal für die Darstellung in Browsern und die Navigation sicher mehr Attribute erforderlich sind, als in einem Dateisystem untergebracht werden können.

        Wenn Du schon eine DB verwendest, hier lassen sich alle Attribute einer darzustellenden Seite, einschließlich Content unterbringen. Hilfreich ist auf jeden Fall OOP, das Ganze wird dann auch einheitlich.

        und würde es gerne ändern und mir dazu vorher mal anschau'n wie es andere machen.

        Siehe meine Seiten ...

        Hotti

        1. hi,

          ich auch nicht, eine virtuelle, fürs Web sichtbare Verzeichnisstruktur auf Dateiebene abzubilden erachte ich als nicht (mehr) sinnvoll. Zumal für die Darstellung in Browsern und die Navigation sicher mehr Attribute erforderlich sind, als in einem Dateisystem untergebracht werden können.

          Wenn Du schon eine DB verwendest, hier lassen sich alle Attribute einer darzustellenden Seite, einschließlich Content unterbringen.

          sorry, das verstehe ich nicht ;(

          gruesse,
          heinetz

  2. Nachtrag:

    Infos, die sicher nicht ganz unerheblich sind:

    • Ich programmiere nicht objekt-orientiert, würde das Projekt aber u.U. irgendwann gerne dahingehend umstellen. Meine Verzeichnisstruktur sollte also für meiner prozeduralen Arbeitweise genauso sinnvoll sein, wie bei mit oop.

    • Sämtliche Unterseiten werden durch eine parametrisiert aufgerufene index.php abgebildet ...

    • ... die aus content.inc.php, header.inc.php, footer.inc.php usw. zusammengesetzt wird.

    • Es gibt Directories, auf deren Inhalte per Webfrontend Einfluss genommen werden kann.

    • Das XHTML der Unterseiten wird vornehmlich in einer MySQL-DB gehalten.

    ...

    gruss,
    heinetz

  3. Hi!

    [...] ich möchte die Situation nutzen, diese Verzeichnisstruktur zu hinterfragen.

    Ja, dann tu das. Mach dir Gedanken, was die Plus- und Minuspunkte an deiner jetzigen Struktur sind.

    Gibt es soetwas, wie einen Standard oder eine Empfehlung, wie die Verzeichnisstruktur optimalerweise für PHP-Projekte aussieht?

    Nein, aber es gibt einige Dinge, die sinnvoll im Allgemeinen sind und welche, die es weniger sind. Beispielsweise sollten Dateien, die nicht über das Web erreichbar sein sollen beziehungsweise es nicht müssen, außerhalb des DocumentRoot abgelegt werden, damit auch beim Ausfall der Schutzmechanismen (Löschen/Überschreiben der Per-Verzeichnis-Konfigurationsdatei (.htaccess)) kein unberechtigter Zugriff auf diese teilweise sensible Daten enthaltenden Dateien entsteht.

    Sowas lässt sich beim Hoster üblicherweise dadurch erreichen, dass man seine Domains nicht auf das Wurzelverzeichnis zeigen lässt, sondern auf ein selbst erstelltes Unterverzeichnis. Einige Provider sind so nett, eine Verzeichnisstruktur bereits eingerichtet zu haben. Da gibt es dann zum Beispiel ein private-Verzeichnis und eins namens htdocs, welches das DocumentRoot der Domain darstellt. Wichtig ist im Grunde genommen nur, dass keine Domain, auch nicht vom Provider bereitgestellte Inklusivdomains, auf dem kundenindividuellen Wurzelverzeichnis verweilen.

    Beispielsweise benutze ich seit jeher eine "config.inc.php", habe aber schon häufiger gesehen, dass sie stattdessen "config.php" heisst.

    Hauptsache ist, dass sie nicht erreichbar ist.

    Lo!

    1. Wow!

      Beispielsweise sollten Dateien, die nicht über das Web erreichbar sein sollen beziehungsweise es nicht müssen, außerhalb des DocumentRoot abgelegt werden, damit auch beim Ausfall der Schutzmechanismen (Löschen/Überschreiben der Per-Verzeichnis-Konfigurationsdatei (.htaccess)) kein unberechtigter Zugriff auf diese teilweise sensible Daten enthaltenden Dateien entsteht.

      Hauptsache ist, dass sie nicht erreichbar ist.

      Das klingt total logisch, bedeutet für mich aber völliges Umdenken!

      Das bedeutet konkret, dass wenn meine Website angenommen nur aus einer index.php besteht, die header.inc.php, content.inc.php und footer.inc.php includiert, keine js, css oder images enthält in dem DocRoot nur index.php und alles andere ausserhalb zu liegen hat.

      Darüber muss ich nachdenken.

      beste gruesse,
      heinetz

      1. Eigentlich ist es nur bei den Konfigurationsfiles wichtig - es sei denn, du willst auch verhindern, dass die Scripte öffentlich einsehbar sein können (wenn z.B. der PHP-Interpreter ausfällt).

        So etwas sollte aber nicht dein primäres Sicherheitskonzept darstellen: wenn jemand die Quelltexte deiner Scripte kennt, darf er dennoch nicht "rein" kommen.

        1. Eigentlich ist es nur bei den Konfigurationsfiles wichtig

          Der Ansatz, alles aus dem DocumentRoot rauszuschmeissen, was nicht direkt per http aufgerufen werden muss, gefällt mir gut. Ich habe irgendwo auf meiner Suche hier diesen Verweis gefunden. Das entspricht dem aus meiner Sicht in etwa. Spricht etwas dagegegen, das konsequent so zu machen?

          gruss,
          heinetz

          1. Spricht etwas dagegegen, das konsequent so zu machen?

            Was dagegen spricht ist, wenn du dein Zeug mal auf einen Server packen musst, wo das nicht möglich ist. Bei vielen Hostern darf man aus dem Root-Verzeichnis nicht raus.

            Zudem gefällt mir bei dem Vorschlag das Mischen des Layouts mit dem Inhalt nicht

            anstat

            img
              content
              layout
            html
            css

            würde ich folgendes vorschlagen

            content
              img
              pdf

            layout
              img
              html
              css
              js

            Das hat den Vorteil, dass beim Tauschen des Layouts prinzipiell nur ein ordner ersetzt werden muss und man nicht in mehreren Ordnern herumsuchen muss ob man ggf. noch Reste/Altlasten vergessen hat, die man entfernen muss.

            1. Hi!

              Spricht etwas dagegegen, das konsequent so zu machen?
              Was dagegen spricht ist, wenn du dein Zeug mal auf einen Server packen musst, wo das nicht möglich ist. Bei vielen Hostern darf man aus dem Root-Verzeichnis nicht raus.

              So einen Hoster will man nicht haben. Und da wir es mit mindestens drei Roots zu tun haben, musst du schon genauer bezeichnen, welches du meinst: Dateisystem-Root, Kunden-Root, DocumentRoot. Wenn man seine grundlegende Struktur wie im verlinkten Artikel aufbauen will, dann ist ein Hoster, der das DocumentRoot nicht umkonfigurieren lässt, für das Projekt ungeeignet. Wenn man von einem solchem Hoster nicht wegkommt, so spricht trotzdem nichts (das mir einfällt) gegen das Aufsetzen einer solchen Struktur, nur dass das ressources-Verzeichnis eben innerhalb des DocumentRoot zu liegen kommen muss. Für einen einfachen Umzug hat man hoffentlich mit derart vorgesorgt, dass der Pfadname in Form einer Variable oder eines Konfigurationseintrags verwendet wird.

              Zudem gefällt mir bei dem Vorschlag das Mischen des Layouts mit dem Inhalt nicht

              Gute Idee, dem Layout (oder jedem einzeln) ein eigenes Verzeichnis zu gönnen und es in ihm zu bündeln.

              Lo!

              1. So einen Hoster will man nicht haben.

                Sag das einem Kunden der _unbedingt_ bei Hoster X hosten lassen will.

                DocumentRoot.

                Ich dachte das ginge aus dem Kontext hervor?

                Für einen einfachen Umzug hat man hoffentlich mit derart vorgesorgt, dass der Pfadname in Form einer Variable oder eines Konfigurationseintrags verwendet wird.

                Natürlich, das ist ohnehin immer schlau - man weiß ja nie, wie die Pfade auf welchem System aussehen werden oder ob man da nicht mal global ran muss.

                1. Hi!

                  DocumentRoot.
                  Ich dachte das ginge aus dem Kontext hervor?

                  In dem Fall, dass man da nicht raus kommt, wäre es dann beides, DocumentRoot und Kunden-Root. Dass man das DocumentRoot nicht innerhalb des Kunden-Root selbst festlegen kann, ist jedoch äußerst ungünstig, wenn der Hoster anbietet, mehrere Domains zu erwerben. Es hat ja relativ wenig Sinn, wenn alle auf das selbe DocumentRoot zeigen müssten.

                  Lo!

                  1. In dem Fall, dass man da nicht raus kommt, wäre es dann beides, DocumentRoot und Kunden-Root. Dass man das DocumentRoot nicht innerhalb des Kunden-Root selbst festlegen kann, ist jedoch äußerst ungünstig, wenn der Hoster anbietet, mehrere Domains zu erwerben. Es hat ja relativ wenig Sinn, wenn alle auf das selbe DocumentRoot zeigen müssten.

                    Bei einigen Hostern ist es so, dass man je "Domain" ein DocumentRoot bekommt die dann nicht notwendigerweise auf demselben Server liegen müssen.

                    Natürlich ist es zu begrüssen, wenn der Kunde einen SSH- (oder meinetwegen FTP-) Zugang hat in dem er sämtliche DocumentRoots sieht, aber das ist nicht immer der Fall.

              2. hi,

                Gute Idee, dem Layout (oder jedem einzeln) ein eigenes Verzeichnis zu gönnen und es in ihm zu bündeln.

                wenn ich sie richtig verstanden habe, finde ich sie auch gut:

                Das Verzeichnis /public_html/layout wird im ganzen ausgetauscht, wenn sich das Layout ändert? Bzw. man legt neben /public_html/layout ein /public_html/layout2 an und die Site ist so mit den selben Inhlaten in zwei Layouts anzuzeigen?

                Wie sieht sie denn nun aus, die vernünftige Verzeichnisstruktur?
                ----------------------------------------------------------------

                Die oberste Ebene scheint mir, klar zu sein: Tennung zwischen Programmlogik
                und per http auszugebenden Inhalten (orientiert an dem Beispiel):

                /public_html
                /ressources

                Als nächstes werden die auszugebenden Inhalte in 'layout' und 'content' eingeteilt. Alles aus 'content' wird ausgegeben, wie in 'layout'
                definiert wird.

                /public_html
                /public_html/content
                /public_html/content/img
                /public_html/content/pdf
                /public_html/layout
                /public_html/layout/css
                /public_html/layout/js
                /public_html/layout/html
                /public_html/layout/img

                We geht's weiter?

                Wie integrierte ich z.B. eine Version der Site für mobile Devices? Logisch
                wäre, wenn ich die Idee richtig verstanden habe, ein Verzeichnis:

                '/public_html/mobile_layout'

                ... , oder? Was mache ich, wenn ich Designelemente (z.B. css-Files) in beiden Versionen verwenden will. Das File aus dem Verzeichnis:

                '/public_html/layout/css'

                ... in das Verzeichnis:

                '/public_html/mobile_layout/css'

                kopieren würde Redundanz bedeuten. Aus:

                'mobile_layout'

                ... auf:

                '../layout'

                ... zugreifen, würde bedeuten, dass ich layout nicht mehr so einfach entsorgen kann.

                beste gruesse,
                heinetz

                1. Das Verzeichnis /public_html/layout wird im ganzen ausgetauscht, wenn sich das Layout ändert? Bzw. man legt neben /public_html/layout ein /public_html/layout2 an und die Site ist so mit den selben Inhlaten in zwei Layouts anzuzeigen?

                  Richtig - und welches der Layouts verwandt wird, kann man z.B. über einen speziellen Parameter oder eine bestimmte REMOTE_ADDR steuern.

                  Wie sieht sie denn nun aus, die vernünftige Verzeichnisstruktur?

                  kopieren würde Redundanz bedeuten.
                  [zu]greifen, würde bedeuten, dass ich layout nicht mehr so einfach entsorgen kann.

                  Richtig - aber das Problem hättest du auch wenn du einen Symlink auf das anderen Layout setzt.

                  Hier ist die Frage ob du zu Redundanzen tendierst oder lieber teilst.

                  Wenn du z.B. zwei Layouts hast - 1x "hell" und 1x "dunkel" die sich nur durch ein paar Farben unterschiedend aber ansonsten identisch sind und auch ansonsten "zusammengehören" sind Redundanzen sicher eine schlechte Wahl.

                  Das musst du für dich selbst entscheiden - oder auch ggf. von Fall zu Fall.

                  1. hi,

                    Das musst du für dich selbst entscheiden - oder auch ggf. von Fall zu Fall.

                    ... und um genau diese Entscheidung so zu treffen, dass sie eine gewisse Zeit Bestand hat, hab ich hier in die Runde gefragt. Und ich habe zwei schöne Ansätze gehört!

                    vielen Dank,
                    heinetz

                2. Hi!

                  Wie sieht sie denn nun aus, die vernünftige Verzeichnisstruktur?

                  "Die" gibt es nicht, besser wäre "eine" und dann ist das auch noch bedarfsabhängig.

                  Wie integrierte ich z.B. eine Version der Site für mobile Devices?

                  Da wäre zunächst die technische Seite zu klären. Eigentlich wäre das nur eine zusätzliche CSS-Datei für ein anderes Ausgabemedium. Das andere Extrem wäre ein komplett eigenes Layout. Für das eine fügst du lediglich eine Datei hinzu, für das andere erstellst du dir eine separate Lyout-Verzeichnisstruktur. Vielleicht geht auch irgendwas dazwischen, also eine zusätzliche CSS-Datei und ein oder mehrere Verzeichnisse für die Mobil-Ressourcen.

                  Was mache ich, wenn ich Designelemente (z.B. css-Files) in beiden Versionen verwenden will.

                  Symlink würden das Problem auf Dateisystemebene lösen. Ein Common-Verzeichnis wäre auch eine Möglichkeit.

                  Lo!

                  1. hi,

                    "Die" gibt es nicht, besser wäre "eine" und dann ist das auch noch bedarfsabhängig.

                    ... das ist mir doch mittlerweile auch klar ;) Bei mir sind mittlerweile zwei sehr gute Ansätze von Dir angekommen und genau die greife ich auf.

                    Ein Common-Verzeichnis wäre auch eine Möglichkeit.

                    ... das erscheint mir als das, was Deinen Ansatz, ein ganzes Layout in einem Ordner zu halten am ehesten verfolgt. Wären dann aber auch schon wieder zwei Verzeichnisse ;)

                    gruss,
                    heinetz

                    1. hi,

                      Ein Common-Verzeichnis wäre auch eine Möglichkeit.

                      ... das erscheint mir als das, was Deinen Ansatz, ein ganzes Layout in einem Ordner zu halten am ehesten verfolgt. Wären dann aber auch schon wieder zwei Verzeichnisse ;)

                      Sorry, ich schmeiss euch beide schon durcheinander. Die Idee mit dem layout-Verzeichnis war ja garnicht Dein Ansatz ;)

                      gruss,
                      heinetz

            2. Was dagegen spricht ist, wenn du dein Zeug mal auf einen Server packen musst, wo das nicht möglich ist. Bei vielen Hostern darf man aus dem Root-Verzeichnis nicht raus.

              ... ich gehe zwar davon aus, dass ich mit *diesem Zeug* niemals umziehen werden muss, aber die Verzeichnisstruktur soll ja eben nicht nur für *dieses Zeug* herhalten, sondern als Standard für zukünftige Projekte werden. Abgesehen davon stehe ich gerade mein meiner Entwicklungsumgebung vor genau der Problematik:

              Mein projekt_1 befindet sich im Verzeichnis /Sites/projekt_1 und ist per http lokal als http://projekt_1.leo.dev erreichbar. DocumentRoot für das Projekt ist also /Sites/projekt_1 (mod_vhost_alias). Das will ich nicht ändern. Sollte es nicht aber mit .htaccess und mod_rewrite möglich sein,
              /public_html zum DocumentRoot zu machen und /ressources zu schützen?

              Damit würde man den Anspruch:

              Beispielsweise sollten Dateien, die nicht über das Web erreichbar sein sollen beziehungsweise es nicht müssen, außerhalb des DocumentRoot abgelegt werden

              ... doch bestmöglich verfolgen.

              • Im Idealfall besteht die Möglichkeit, das Unterverzeichnis /public zum DocRoot zu machen.

              • Besteht diese Möglichkeit nicht, regelt man das per .htaccess und die Site funktioniert auch.

              Zudem gefällt mir bei dem Vorschlag das Mischen des Layouts mit dem Inhalt nicht

              anstat

              img
                content
                layout
              html
              css

              würde ich folgendes vorschlagen

              content
                img
                pdf

              layout
                img
                html
                css
                js

              Das hat den Vorteil, dass beim Tauschen des Layouts prinzipiell nur ein ordner ersetzt werden muss und man nicht in mehreren Ordnern herumsuchen muss ob man ggf. noch Reste/Altlasten vergessen hat, die man entfernen muss.

              Bis über die 2. Ebene hinaus hatte ich mir das garnicht angeschaut. Das sähe bei mir eh anders aus:

              /public/_admin/
              /public/_content/
              /public/_content/css
              /public/_content/img
              /public/_content/js
              /public/_content/upload
              /public/_content/upload/img
              /public/_content/upload/pdf
              ...

              gruesse,
              heinetz

      2. Hi!

        Das bedeutet konkret, dass wenn meine Website angenommen nur aus einer index.php besteht, die header.inc.php, content.inc.php und footer.inc.php includiert, keine js, css oder images enthält in dem DocRoot nur index.php und alles andere ausserhalb zu liegen hat.

        Wenn du das so formulierst, habe ich den Eindruck, dass du noch Schwierigkeiten hast, die Gemengelage aus verschiedenen Blickwinkeln betrachten zu können. Zwischen Javascript, CSS und anderen eingebundenen Ressourcen und dem den Verweis erzeugenden/enthaltenden Programm- oder Templatecode besteht kein Zusammenhang, was seinen Platz im Dateisystem des Webservers anbelangt.

        Möglicherweise hast du bisher Verweise, die durch inkludierten Code ausgegeben werden, immer relativ zu diesem Code oder vielmehr relativ zum inkludierenden Script angegeben. Die Verweise müssen aber relativ zu dem formuliert sein, was der Browser zu sehen bekommt. Schau dir an, wie es der Browser benötigt und programmier deine Scripte, Inklude-Dateien und Templates so, dass genau der vom Browser benötigte Verweis-Code erzeugt wird.

        Lo!

        1. hi,

          Wenn du das so formulierst, habe ich den Eindruck, dass du noch Schwierigkeiten hast, die Gemengelage aus verschiedenen Blickwinkeln betrachten zu können. Zwischen Javascript, CSS und anderen eingebundenen Ressourcen und dem den Verweis erzeugenden/enthaltenden Programm- oder Templatecode besteht kein Zusammenhang, was seinen Platz im Dateisystem des Webservers anbelangt.

          Möglicherweise hast du bisher Verweise, die durch inkludierten Code ausgegeben werden, immer relativ zu diesem Code oder vielmehr relativ zum inkludierenden Script angegeben. Die Verweise müssen aber relativ zu dem formuliert sein, was der Browser zu sehen bekommt. Schau dir an, wie es der Browser benötigt und programmier deine Scripte, Inklude-Dateien und Templates so, dass genau der vom Browser benötigte Verweis-Code erzeugt wird.

          das verstehe ich schon wieder nicht ;(

          Ich hatte Deine Aussage so verstanden, dass nur was direkt per http aufrufbar sein soll auch im DocumentRoot liegen muss und deshalb auch nichts anderes dort liegen sollte. Das erschien mir logisch, denn so muss man sich nicht darum kümmern, zu verhindern, dass irgendetwas per http aufgerufen werden kann, was garnicht per http aufgerufen werden können soll. Diesem Grunsatz folgendend würde bei einer noch so komplexen PHP-Site, die OHNE Grafiken, CSS- und JS-Files auskommt und sämtliche Inhalte von einer mit Parametern aufgerufenen index.php angezeigt werden nur die
          eine Datei index.php im DocumentRoot zu liegen haben und alles, was von sonstwo includiert wird, muss dort nicht liegen und sollte von sonstwo ausserhalb inkludiert werden.

          relative gruesse,
          heinetz

          gruss,
          heinetz

          1. Hi!

            das verstehe ich schon wieder nicht ;(

            Vielleicht hab ich auch nur etwas missgedeutet, weil du da clientseitige Dinge wie js, css, img an einer Stelle erwähntes, wo es doch nur um die serverseitige Organisation der Code-Dateien ging. Zudem hab ich mich auch nicht einfach und verständlich auszudrücken vermocht.

            Ich hatte Deine Aussage so verstanden, dass nur was direkt per http aufrufbar sein soll auch im DocumentRoot liegen muss und deshalb auch nichts anderes dort liegen sollte.

            Ja.

            Das erschien mir logisch, denn so muss man sich nicht darum kümmern, zu verhindern, dass irgendetwas per http aufgerufen werden kann, was garnicht per http aufgerufen werden können soll.

            Ja.

            Diesem Grunsatz folgendend würde bei einer noch so komplexen PHP-Site, die OHNE Grafiken, CSS- und JS-Files auskommt und sämtliche Inhalte von einer mit Parametern aufgerufenen index.php angezeigt werden nur die eine Datei index.php im DocumentRoot zu liegen haben und alles, was von sonstwo includiert wird, muss dort nicht liegen und sollte von sonstwo ausserhalb inkludiert werden.

            Genau. Und nun dachte ich, dass du da eine untrennbare Einheit zwischen den PHP-Codeteilen, die den HTML-Teil mit den Ressourcen-Verweisen drin erzeugen, und den Ressourcen selbst siehst, und damit einen Konflikt, weil die Ressourcen öffentlich sein müssen, der Code dazu aber intern liegt. Wenn ich da aber falsch lag, dann ist die ganze Aufregung ja gegenstandslos.

            Lo!