[PHP] Dynamisch Inhalte einbinden

jeko

Lounge-Member
Hier das kleine Prinzip des Einbinden von externen PHP-Dateien, wie es auch verwendet wird um den Inhalt einer Seite dynamisch einzubinden. Dies hat den Vorteil, dass wenn ihr z.B. immer den gleichen Header und Footer (Kopf- und Fussbereich) habt, ihr die beiden nicht auf jeder Seite nochmal einbinden müsst.

Zuerst macht ihr eure index.php, bzw. euer Hauptdokument. In diesem Dokument befindet sich der statische Header (das kann ein Banner oder sonstwas sein, was einfach immer auf eurer Seite zu sehen sein muss) und den Footer (gleiche Eigenschaften wie Header).
PHP:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<!-- Hier natürlich das übliche Zeug, Titel, einbinden von Script-/Css-/anderer Dateien. -->
<title>Dynamische Inhalte</title>
<link rel="stylesheet" type="text/css" href="euer_Css_file.css" />
</head>
<body>
<!-- Hier ist kommt euer satische obere Teil hin -->
<div id="banner"><img src="banner.jpg" alt="banner" /></div>
<div id="menu"><ul><li><a href="?dir=punkt1">Punkt1</a></li><li><a href="?dir=punkt2">Punkt2</a></li></ul></div>

<!-- Jetzt kommts. Hier soll also der spezifische Inhalt hin. -->
<?php
/* Das Einbinden funktioniert folgendermassen: Wie ihr sicher bemerkt habt, hab ich in die Href-Angaben der Menu-Links "?dir=" reingeschrieben. Dies übergibt der index.php eine Variable mit einem Wert. Der Wert ist der menu-Punkt der geklickt wurde. An diesen Wert kommen wir mit dem Global array $_REQUEST.
Also speichern wir uns den Wert mal ab. */

$direction = ( isset($_REQUEST['dir']) && !empty($_REQUEST['dir']) ) ?    $_REQUEST['direction'] : FALSE;
// Diese Zeile weist $direction den Wert der übergebenen Variable zu. Falls diese nicht gesetzt wurde (d.h. Url ohne "?dir="), wird der Wert auf FALSE gesetzt.

//So, nun müssen wir ein array machen, das die Zeiger und ihre Dateien beinhält. 
$the_sites = array(
'punkt1' => "punkt1.php",
'punkt2' => "punkt1.php",
'404' => "fehler404.php"
);

if ($direction == FALSE) {
$direction = '404';
}
// wenn kein "?dir=" in der URL, wissen wir nicht was einbinden. Die Datei "fehler404.php" ist sozusagen eine Fallbacklösung.

// So. Nun  kommt der Hauptteil.

if( isset($the_sites[$dir]) ) {
//gibt es den Zeiger in unserem Array?
include_once('./'.$the_sites[$dir]);
/* Hier wird ein Pfad erstellt $the_sites[$dir] gibt die Datei zurück, die im Array mit dem jeweiligen Wert von $dir verbunden ist. Bei $dir = "punkt1" wird hier "punkt1.php" zurückgegeben. Danach stände bei diesem Beispiel: include_once("./punkt1.php");
include_once liest den Inhalt der angegebenen Datei aus und fügt ihn an der Stelle ein, wo include_once steht. Dieselbe Datei wird durch include_once nur einmal im gesamten Dokument eingefügt. */
} else {
// wenn es zu $dir nichts in unserem Array gibt.
header('HTTP/1.0 404 Not Found');
// 404-Header senden
include_once('./'.$valid_sites['fehler404']);
// und die Fallback-"Lösung" einbinden.
}
//Fertig.
?>
<!-- Hier kann jetzt noch der Footer folgen... -->
<div id="footer"><p>Copyright by WebmastXY</p></div>
</body>
</html>
So. Nun wenden wir uns den Dateien zu, welche die Inhalte enthalten.
Wir müssen also jetzt für jeden Wert im $the_sites-Array eine .php-Datei erstellen.
Die Datei für Punkt1 wäre zum Beispiel so:
punkt1.php
PHP:
<?php
echo '
<h1>jaja...</h1>
<p>Du hast Punkt1 geklickt. Das gibt einen Punkt!</p>';
?>

Wichtig ist, dass die PHP-Markierungen (<?php und ?>) stehen und dass die Endung .php ist.
Im Quelltext, der an den Browser des Clients geschickt wird, wenn dieser auf "Punkt1" im Menu geklickt hat, wäre dann:
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<!-- Hier natürlich das übliche Zeug, Titel, einbinden von Script-/Css-/anderer Dateien. -->
<title>Dynamische Inhalte</title>
<link rel="stylesheet" type="text/css" href="euer_Css_file.css" />
</head>
<body>
<!-- Hier ist kommt euer satische obere Teil hin -->
<div id="banner"><img src="banner.jpg" alt="banner" /></div>
<div id="menu"><ul><li><a href="?dir=punkt1">Punkt1</a></li><li><a href="?dir=punkt2">Punkt2</a></li></ul></div>

<!-- Jetzt kommts. Hier soll also der spezifische Inhalt hin. -->
<h1>jaja...</h1>
<p>Du hast Punkt1 geklickt. Das gibt einen Punkt!</p>
<!-- Hier kann jetzt noch der Footer folgen... -->
<div id="footer"><p>Copyright by WebmastXY</p></div>
</body>
</html>

Ich hoffe es war verständlich und ihr habt was gelernt.
Hier noch einige Links zum Thema:
 
dein script müsste eigentlich eine fehlermeldung ausgeben, da die header()-funktion nach dem ersten output aufgerufen wird. lösung: die überprüfung vor der ersten ausgabe abwickeln oder den output buffern.
 
Stimmt. In diesem Zusammenhang noch bitte nach den Funktionen ob_start und ob_end_flush nachschlagen.
 
jeko schrieb:
$direction = ( isset($_REQUEST['dir']) && !empty($_REQUEST['dir']) ) ? $_REQUEST['direction'] : FALSE;

warum so kompliziert ??
es reicht doch auch nur mit isset zu fragen.
Code:
else
{
$direction = "home.htm";
}
würde doch reichen
bei else (also wenn die variable nicht gesetzt ist) lasse ich dann die Startseite öffnen.

statt $_REQUEST['dir'] kann man auch $_GET['dir'] nehmen, oder gibt es da einen Unterschied ?
 
Hi sLost!

Klar, das kann man auch so machen. Ich habs damals eigentlich so gelöst, damit es bisschen übersichtlicher wird, und vielleicht etwas besser erklärt ist. Man könnte eigentlich auch gleich sowas machen:
PHP:
$direction = ( isset($_REQUEST['dir']) && !empty($_REQUEST['dir']) ) ?    $_REQUEST['direction'] : 'punkt1';
Meintest du das?

Und zum andern. Mit dem $_GET-Array bekommst du alle Variablen die per GET, also in der URL mitgegeben werden. Mit dem $_POST-Array bekommst du alle Varisablen die per POST, also in den Headern mitgegeben werden. Mit dem $_REQUEST-Array bekommst du Zugriff auf _alle_ Variablen, egal ob POST oder GET :)
Ist eigentlich in diesem Beispiel nicht unbedingt nötig, es wird dadurch einfach flexibler, da es auch mit POST-Vars funktioniert :)
 
hab das ma ausprobiert, klappt nich... :(
hab bestimmt irgend nen kleinen fehler gemacht, der mir wieder nich auffällt!
die seite: kennt ihr ja schon zu genüge ;)

PHP:
<?php
 
   $ziel = (isset($_REQUEST['go']) && !empty($_REQUEST['go']) ) ?    $_REQUEST['go'] : FALSE;
   $sites = array
(

        'home' => "home.php",
     'company' => "comp.php",
     'contact' => "cont.php",
     'imprint' => "impr.php",
         'top' => "top.php",
  'innenlager' => "inne.php",
  'garnituren' => "garn.php",
 'zahnkraenze' => "zahn.php",
 'heimtrainer' => "heim.php",
         '404' => "fehler404.php"
);

if ($ziel == FALSE) { 
$ziel = $sites['404']; 
}

if(isset($sites[$go]) ) {
 include_once('./'.$sites[$go]);
} else {
 header('HTTP/1.0 404 Not Found');
 include_once($sites['404']);
} ?>

//edit: der Hom-link geht, weil er existiert... bei den anderen kommt ne fehlermeldung statt der fehler404.php...
 
Zuletzt bearbeitet:
Sehr gut. Dein Fehler ist/war:

Du musst natürlich alle Links die Variable mit dem Ziel übergeben lassen. Zum Beispiel bei 'Unternehmen' verlinkst du auf 'company.php'. Das ist absoluter Quatsch. Du musst wenn überhaupt auf '?go=company' oder 'index.php?go=company' verweisen (schau oben die Menueinträge an, Punkt 1 etc.).
 
Da hier noch der Hinweis auf den Header kam, der nicht funzt wegen der Ausgabe davor, hier die Lösung dazu:

Um Header senden zu können, darf vorher nichts Ausgegeben werden. Dies kann man entweder lösen, durchdas man einfach keine Daten an den Ausgabestream schickt, also keine echos oder prints vor der header()-Funktion oder aber puffert die Ausgaben. Die erstere Methode benötigt einfach etwas mehr Vorsicht und produziert etwas unübersichtlicheren Code (in den _meisten_ Fällen). Daher wäre ich für's Puffern.
Die Ausgaben kann man mit dem Befehl ob_start() puffern lassen. Beim Puffern wird alles was an den Ausgabestream gesendet wird, umgeleitet in den sogenannten Puffer. Dieser Puffer wird immer weiter gefüllt, mit jeder Ausgabe die ansonsten an den Client geschickt werden würde. Am Ende des Scripts, oder mit dem ob_flush() (oder mit einer Zusammengesetzten Funktion wie ob_get_flush oder ob_end_flush) wird der Inhalt des Puffers an den Client gesendet und der Puffer geleert.

Nun, wir haben 2 Fakten.
-> Vor header() darf nichts an den Client geschickt werden.
-> ob_start() puffert die Ausgabe und man kann steuern, wann etwas an den Client geschickt werden soll.

Vorgehen: Ausgabe puffern, header() ausführen, Pufferinhalt senden.

Umsetzung: Am einfachsten ist es, ob_start() an den Anfang des Dokuments zu setzen. Da ob_start() erst dann beginnt die Ausgabe zu puffern, muss also jede Ausgabe nach ob_start() erfolgen. Alles was vorher ausgegeben wird, wird gleich an den Client geschickt.
-> Die Pufferung kann auch beendet werden mit [http://php.net/ob_end()]ob_end[/url] (oder einer Zusammengesetzten Funktion wie ob_end_clean() oder ob_end_flush). Alles was nach ob_end() kommt, würde also wieder an den Client geschickt werden.
Also, wir aktivieren die Pufferung.
PHP:
<?php
ob_start();
// Restlicher Code...
Somit wird alles gepuffert, was ausgegeben würde. Wenn wir nun also an die Headerstelle kommen,
PHP:
} else {
// wenn es zu $dir nichts in unserem Array gibt.
header('HTTP/1.0 404 Not Found');
// 404-Header senden
}
könnte der 404-Header erfolgreich gesendet werden. Vorher wird nichts an den Client geschickt (Ausgabepufferung), andere Befehle funktionieren jedoch (wie auch Header, der zwar auch etwas an den Client schickt, jedoch das nicht in die Zuständigkeit des Puffers fällt) normal.

Am Ende der Scriptausführung wird der Puffer automatisch geleert, das heisst eine ob_end() wäre nicht nötig. Zum Verständnis und zur Eloquenz des Codes mach ich's hier trotzdem. Und zwar verwende ich die zusammengesetzte Funktion aus ob_end() (Beenden der Pufferung) und ob_flush (Senden & leeren des Puffers), nämlich ob_end_flush(). Sie sendet den Inhalt des Puffers, leert den Puffer und beendet die Pufferung, alles in einem.
PHP:
ob_end_flush();
?>
Ich hoffe damit sind allfällige Fragen geklärt.
 
Ein Link, der über mögliche Risiken aufklärt, welche entstehen bei einer direkten Einbindung einer $_GET-Variable.
Injection - php bar

Passt zum Topic insofern, als dass mit der hier besprochenen Methode solche Übergriffe abgefangen werden können.
 
Hallo. Ich würde auf diese Methode auf meiner HP gerne die Links gestalten. Allerdigs verstehe ich die Zeile:
$direction = ( isset($_REQUEST['dir']) && !empty($_REQUEST['dir']) ) ? $_REQUEST['direction'] : FALSE;
nicht wirklich. Und als ich mich noch auf anderen Seiten im i-net informieren wollte, musste ich feststellen, dass das hier irgendwie das einzige Forum ist, welches diese Methode beschreibt. Wenn ich bei google "per Include Links einbinden" oder so eingebe, kommt nur die Methode, per include() Inhalte einzubinden, aber nicht so, dass ich auf den Links klicke und er lädt keine neue Seite mit nem Include-Befehl, sondern halt gleich den Inhalt einer anderen Seite wie hier..
Deswegen wäre ich dankbar, wenn ihr mir die besagt Zeile anfängergerrecht erläutern könntet :)

Gruß Maxx
 
Das ist ne verkürzte Version einer if-Abfrage mit Zuweisung.
Etwas länger:

PHP:
if(isset($_REQUEST['dir']) && !empty($_REQUEST['dir']))
{
   // Wenn $_REQUEST['dir'] existiert und nicht leer ist, wird der Wert in $direction gespeichert...
   $direction = $_REQUEST['dir'];
}
else
{
   // sonst steht in $direction false.
   $direction = false;
}

was empty sein bedeutet: PHP: empty - Manual
PHP: empty - Manual
 
Danke! Aber wenn ich den Code einbinde, kommt beim klick auf den Link nur eine Warnung in Zeile 43/45:
<?php

ob_start();

$direction = ( isset($_REQUEST['dir']) && !empty($_REQUEST['dir']) ) ? $_REQUEST['direction'] : FALSE;

$the_sites = array(
'kontakt' => "php/kontaktformular/kontakt.php",

);

if ($direction == FALSE) {
$direction = '404';
}
// wenn kein "?dir=" in der URL, wissen wir nicht was einbinden. Die Datei "fehler404.php" ist sozusagen eine Fallbacklösung.



if( isset($the_sites[$dir]) ) {
//gibt es den Zeiger in unserem Array?
include_once('./'.$the_sites[$dir]);



} else {

header('HTTP/1.0 404 Not Found');

include_once('./'.$valid_sites['fehler404']);

}
//Fertig.

ob_end_flush();

?>

<a href="?dir=kontakt">Anfragen</a>

Die Warnungen, die ich erhalte, sind folgende:
Warning: Cannot modify header information - headers already sent by (output started at C:\xampplite\htdocs\stayfolk\index.php:8) in C:\xampplite\htdocs\stayfolk\index.php on line 40

Warning: include_once(./) [function.include-once]: failed to open stream: No such file or directory in C:\xampplite\htdocs\stayfolk\index.php on line 42

Warning: include_once() [function.include]: Failed opening './' for inclusion (include_path='.;C:\xampplite\php\pear\') in C:\xampplite\htdocs\stayfolk\index.php on line 42
 
Du solltest vll. auch mal die index.php posten, bzw. hat dein Ausschnitt keine 40 Zeilen (36), was darauf schliessen lässt, dass weiter oben oder unten deines Snippets sich weiterer Code versteckt.

Die Inclusionfehler rühren zum Einen daher, dass du den Wert der Get-Variable in die Variable $direction ablegst, danach jedoch mit $dir weiterfährst.
Zum Andern, dass zum Index 'fehler404' kein Eintrag in deinem Array $the_sites besteht.

Grüsse
jeko
 
ok also hier einmal der ganze code der index:
<body>

<?php

ob_start();

$direction = ( isset($_REQUEST['dir']) && !empty($_REQUEST['dir']) ) ? $_REQUEST['direction'] : FALSE;

$the_sites = array(
'kontakt' => "php/kontaktformular/kontakt.php",

);

if ($direction == FALSE) {
$direction = '404';
}
// wenn kein "?dir=" in der URL, wissen wir nicht was einbinden. Die Datei "fehler404.php" ist sozusagen eine Fallbacklösung.



if( isset($the_sites[$dir]) ) {
//gibt es den Zeiger in unserem Array?
include_once('./'.$the_sites[$dir]);



} else {

header('HTTP/1.0 404 Not Found');

include_once('./'.$valid_sites['fehler404']);

}
//Fertig.

ob_end_flush();

?>

<table class="layout_tabelle">
<!--Beginn - banner-->
<tr>
<td colspan="3" id="banner">

</td>
</tr>
<!--Ende - banner-->

<!--Beginn - menu_-->
<tr>
<td id="menu_L">

</td>
<td id="menu_M"> <ul id="MenuBar1" class="MenuBarHorizontal">
<li><a href="#">Startseite</a> </li>
<li><a href="#" class="MenuBarItemSubmenu">Informationen</a>
<ul>
<li><a href="#">Das Festival</a></li>
<li><a href="#">Bands</a></li>
<li><a href="#">Presse</a></li>
<li><a href="#">Anfahrt</a></li>
<li><a href="#">Newsletter</a></li>

</ul>
</li>
<li><a href="#">Gästebuch</a> </li>
<li><a href="#">Galerie</a></li>
<li><a href="#" class="MenuBarItemSubmenu">Kontakt</a>
<ul>
<li><a href="#">Tickets</a></li>
<li><a href="?dir=kontakt">Anfragen</a></li>
<li><a href="#">Ansprechpartner</a></li>
<li><a href="#">Impressum</a></li>
</ul>
</li>
<li><a href="#">Links</a></li>
</ul>
</td>
<td id="menu_R">

</td>
</tr>
<!--Ende - menu_-->

<!--Beginn - main-->
<tr>
<td colspan="3" id="main">

</td>
</tr>
<!--Ende - main-->
<!--Beginn - zw_3-->

<tr>
<td id="zw_3_L">

</td>
<td id="zw_3_M">

</td>
<td id="zw_3_R">

</td>
</tr>
<!--Ende - zw_3-->
<!--Beginn - foot-->
<tr>
<td colspan="3" id="foot">

</td>
</tr>
<!--Ende - foot-->
</table>
<script type="text/javascript">
<!--
var MenuBar1 = new Spry.Widget.MenuBar("MenuBar1", {imgDown:"SpryAssets/SpryMenuBarDownHover.gif", imgRight:"SpryAssets/SpryMenuBarRightHover.gif"});
//-->
</script>
</body>
 
header() kann keine Ausgabe an den Browser senden, wenn bereits ausgaben erfolgt sind. In deinem Fall ist das das HTML und die whitespaces vor dem <?php
 
Habe:
else {

header('HTTP/1.0 404 Not Found');

include_once('./'.$valid_sites['fehler404']);
etfernt. FUnktioniert trotzdem nicht...
Irgendwie raffe ich auch die Funktionsweise nicht wirklich. Habt ihr vielleciht eine net-Adresse, wo genau das beschrieben wird? dann könnte ich mich informieren; aber ich finde nichts dazu.

gruß Maxx
 
Die Poster oberhalb haben eigentlich schon alles gesagt, noch ein Tipp von mir: ob_start() muss _vor_ der ersten Ausgabe stehen. Also noch bevor deine HTML-Ausgabe beginnt. Am Besten du nimmst das ob_start() an den Beginn der index.php (Voraussetzung: Index.php wird nicht selber noch eingebunden).
 
Zurück
Oben