sonne: Wie richtig include, so das der Pfad immer korrekt ist?

Hallo zusammen, wenn ich von folgender Verzeichnisstruktur ausgehe

-home-
    index.php
/content    
    /verzeichnis_1
        /verzeichnis_1_a
            seite_a_1.php
        /verzeichnis_1_b
            seite_b_1.php
/includes
    header.php
    nav-bar.php
/layout
    /styles
        main.css
/navigation
    navi.php

und in der index.php die header.php und die nav-bar.php per include einbinde funktioniert es wie gewünscht.
Wenn ich das aber mit der *seite_a_1.php * mache werden z.b. die css Dateien nicht eingebunden. Meine Versuche haben ergeben das dann der Pfad zu den css Dateien nicht korrekt ist. Wie mache ich es richtig.

header.php

<!DOCTYPE html>
<html lang="de">
<head>
<title>xyz</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="./layout/styles/main.css" rel="stylesheet" type="text/css" media="all">
<link href="./layout/styles/mediaqueries.css" rel="stylesheet" type="text/css" media="all">
<!-- css für navigation -->
<link rel="stylesheet" href="./layout/styles/style.css">
</head>

Wenn ich ./layout/styles/main.css durch ../../../layout/styles/main.css ersetze werden die css Dateien in der seite_a_1.php eingebunden aber natürlich nicht in der index.php

  1. Moin,

    ich habe deinen Code der Lesbarkeit halber entsprechend gekennzeichnet, das kannst Du in Zukunft auch, also

    ~~~html
    <p>als <abbr title="HyperText Markup Language" lang="en">HTML</abbr>
    ausgezeichneter <em>Code</em></p>
    ~~~
    

    ergibt:

    <p>als <abbr title="HyperText Markup Language" lang="en">HTML</abbr>
    ausgezeichneter <em>Code</em></p>
    

    Viele Grüße
    Robert

    1. Danke schön!

  2. Moin,

    wenn ich von folgender Verzeichnisstruktur ausgehe

    -home-
        index.php
    

    Was heißt das -home- hier genau? Liegt die index.php im obersten Verzeichnis neben content, includes, …?

    /content    
        /verzeichnis_1
            /verzeichnis_1_a
                seite_a_1.php
            /verzeichnis_1_b
                seite_b_1.php
    /includes
        header.php
        nav-bar.php
    /layout
        /styles
            main.css
    /navigation
        navi.php
    

    und in der index.php die header.php und die nav-bar.php per include einbinde funktioniert es wie gewünscht.

    Was ist „es“ und was heißt „funktioniert wie gewünscht“?

    Wenn ich das aber mit der *seite_a_1.php * mache werden z.b. die css Dateien nicht eingebunden. Meine Versuche haben ergeben das dann der Pfad zu den css Dateien nicht korrekt ist. Wie mache ich es richtig.

    In dem Du den richtigen Pfad aus Sicht der jeweiligen Datei angibst.

    Wenn ich ./layout/styles/main.css durch ../../../layout/styles/main.css ersetze werden die css Dateien in der seite_a_1.php eingebunden aber natürlich nicht in der index.php

    Deshalb meine Eingabgsfrage, wie index.php relativ zu den anderen Verzeichnissen liegt.

    Wenn die index.php im Document Root liegt, sollten aus ihrer Sicht und der des Webservers diese Pfade zur gleichen Ressource führen:

    • ./layout/styles/main.css
    • layout/styles/main.css (äquivalent zur vorherigen Zeile)
    • ../../../layout/styles/main.css (sofern /index.php – der Versuch in den übergeordneten Pfad zu wechseln würde normalisiert)
    • /layout/styles/main.css (von der Document Root aus)

    Viele Grüße
    Robert

    1. genau, die index.php liegt im obersten Verzeichnis.

      Das, mein Problem ist, wenn ich eine Datei per inlude einbinde, z.B. die header.php der Pfad für die css-Dateien für die index.php korrekt ist aber z.B. für die seite_1_a im Verzeichnis content nicht mehr passt. Ich habe es erfolglos mit absolut Pfad angaben in der header.php probiert.

      1. Moin,

        genau, die index.php liegt im obersten Verzeichnis.

        für mich sieht das so aus, als läge die index.php in verzeichnis_1.

        Das, mein Problem ist, wenn ich eine Datei per inlude einbinde, z.B. die header.php der Pfad für die css-Dateien für die index.php korrekt ist aber z.B. für die seite_1_a im Verzeichnis content nicht mehr passt. Ich habe es erfolglos mit absolut Pfad angaben in der header.php probiert.

        Also wenn das PHP auf dem Server ausgeführt wird und nach Deiner Beschreibung die index.php im Document Root liegt, dann sehe ich keinen plausiblen Grund, warum der absolute Pfad /layout/styles/main.css gemäß des Ausgangsbeitrags nicht funktionieren sollte, wenn PHP per HTTP aufgerufen wird.

        Viele Grüße
        Robert

      2. Liebe(r) sonne,

        mein Problem ist, wenn ich eine Datei per inlude einbinde,

        nein, Dein Problem ist, dass Du nicht nur ein zentrales Script aufrufst, sondern viele verschiedene. Damit schießt Du Dir nur selbst ins Knie. Es gäbe da eine Lösung, aber die musst Du halt wollen...

        Liebe Grüße

        Felix Riesterer

  3. Liebe(r) sonne,

    das Problem hättest Du erst gar nicht, wenn Du nicht zig PHP-Scripte hättest, sondern nur eines.

    example.com/home/index.php/impressum
    example.com/home/index.php/kontakt
    example.com/home/index.php/agb
    

    Diese URLs zeigen immer wieder auf ein und dasselbe PHP-Script, nämlich index.php. Innerhalb dessen kannst Du nun mit $_SERVER['PHP_SELF'] den Pfad auslesen (z.B. /home/index.php/kontakt) und im Script entsprechend darauf reagieren.

    Deinen Content könntest Du wie gehabt im Verzeichnis /content bereit halten (vor direkten Aufrufen aus dem Browser heraus schützen!) und von index.php aus inkludieren. Oder Du speicherst den Content in einer XML-Datei. Oder in einer Datenbank. Da gibt es ja mehrere Möglichkeiten.

    Templates könnten Dir übrigens genau in dieser Sache sehr gut helfen: Tutorial zu Templates

    Liebe Grüße

    Felix Riesterer

    1. Hallo Felix Riesterer,

      Hinweis: im Apache muss

      AcceptPathInfo On

      gesetzt sein, sonst funktioniert das nicht.

      Rolf

      --
      sumpsi - posui - obstruxi
      1. n'Abend,

        Hinweis: im Apache muss

        AcceptPathInfo On

        gesetzt sein, sonst funktioniert das nicht.

        das ist aber meines Wissens die Voreinstellung. Insofern ist der Hinweis richtig, aber in den meisten Fällen irrelevant.

        Einen schönen Tag noch
         Martin

        --
        Wichtige Erkenntnis für Comiczeichner:
        Eine Sprechblase ist nicht unbedingt ein Fall für den Urologen.
  4. Hallo sonne,

    du musst unterscheiden zwischen dem Dateisystem auf deinem Server und der Dateihierarchie, die der Server dem Browser präsentiert.

    Die Seite https://www.example.org/index.php befindet sind im Web-Root von https://www.example.org. Dein Ordner layout befindet sich dort ebenfalls. Die Seite https://www.example.org/content/bla.php befindet sich hingegen in einem Unterordner des Web-Root und deshalb funktioniert der Pfad "./layout/..." nicht, weil der Punkt ja sagt, dass der Pfad relativ zum Ordner sein soll, aus dem das Dokument kommt.

    Das ist ein grundsätzliches Problem, wenn man Stylesheets aus Includes einbindet. Das Einbinden über einen relativen Pfad führt eigentlich immer ins Chaos. Solange die ganze Webanwendung im Web-Root liegt, ist es aber einfach lösbar: Binde Ressourcen grundsätzlich über eine absolute Pfadangabe ein. Und solange es nur einen Layout-Order gibt, verwendet man einfach immer /layout/styles/main.css.

    Schwieriger wird das, wenn die Ressourcen ebenfalls aus unterschiedlichen Quellen stammen und DAS noch mit Include-Komplexen kombiniert wird. Wenn ich also /module-1/block-c/index.html abrufe, darin /common/header.php include und erwarte, dass dieses Include von unterschiedlichen Modulen verwendet werden kann und die lokalen Stylesheets des jeweiligen Moduls einfügt. Das Include braucht dann Intelligenz. Es kann $_SERVER['SCRIPT_NAME'] analysieren, um sich schlau zu machen. Man könnte auch definieren, dass eine index.html eine globale Variable $module_resources festlegen muss, worin der richtige Pfad steht.

    Besser ist dann aber ein abstrahiertes System, das URLs wie https://www.example.org/kunde/573 verwendet. Im Apache verwendet man das mod_rewrite, um diese URL auf https://www.example.org/index.php?exec=kunde/show/573 umzuschreiben, und index.php kümmert sich dann darum, dass das richtige Modul geladen wird und darin die passende Funktion abgerufen wird. Das ist auch nicht einfach - überhaupt nicht einfach - aber es ermöglicht die Trennung von Komponenten und das zentrale Erledigen von Aufgaben, die zur Verkabelung des Ganzen nötig sind. Was Felix vorschlägt, läuft in die gleiche Richtung, versteckt aber die index.php nicht.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Vielen Dank für die hilfreichen Antworten. Dadurch das ich die meine Scripte zusammengefasst habe und wo nötig absolute Pfade bzw. den Pfad mit $_SERVER['DOCUMENT_ROOT'] bestimme funktioniert es schon besser.
      Es zeigt aber auch das dass auslagern von wiederkehrende Elemente in eigene Dateien sehr gut geplant werden muss.

      Danke und Grüße