SELFPHP

SELFPHP-Druckversion
Original Adresse dieser Seite:
http://www.selfphp.de/praxisbuch/praxisbuch.php?group=40
© 2001-2017 E-Mail SELFPHP OHG, info@selfphp.de
© 2005-2017 E-Mail PHP5 Praxisbuch - Matthias Kannengiesser, m.kannengiesser@selfphp.de


Online-Gästebuch


Nun sollten Sie versuchen, sich mit einem etwas komplexeren Problem zu befassen, nämlich der Umsetzung eines Gästebuchs. Ein Gästebuch findet man heutzutage auf einer Vielzahl von Websites, ob bei Privatpersonen, Firmen oder Vereinen. Es seinen Besuchern zu ermöglichen, eine Nachricht zu hinterlassen, hatte schon immer einen gewissen Reiz.

Das Gästebuch setzt sich aus folgenden Dateien zusammen:

Sowohl die main.css als auch die automail.txt befinden sich in einem jeweils gesonderten Ordner. Folgende Ordner sorgen für Übersicht:




Bild 5.5: Dateischema des Atomic-Gästebuchs

Nun sollten Sie einen Blick auf die eingesetzten Skripts werfen:{PSP}1. Buch_eintrag.php

<html>
<head>
<title>Gästebuch v1.0</title>
<link rel='stylesheet' href='css/main.css' type='text/css'>
</head>
<body bgcolor='#FFFFFF' text='#000000'>
<p align='center'><img src='bild/gbuchlogo.gif' width='800' height='80'></p>
<form method='post' action='buch_funktionen.php'>
  <table width='400' align='center'>
    <tr align='left'>
      <td class='latestnews' colspan='6'> Kommentar</td>
    </tr>
    <tr>
      <td colspan='6' class='autor' height='10'>
        <div align='right'></div>
      </td>
    </tr>
    <tr>
      <td valign='top' width='9'>
        <div class='morelink'>» </div>
      </td>
      <td valign='top' class='blocksatz' width='36'>Name: </td>
      <td valign='top' class='blocksatz' width='190'>
        <input type='text' name='fname' class='contentblack' size='30' maxlength='50'>
      </td>
      <td valign='top' class='morelink' width='6'>»</td>
      <td valign='top' class='blocksatz' width='40'>Rubrik:</td>
      <td valign='top' class='blocksatz' width='91'>
        <select name='fbetreff' class='contentblack'>
          <option value='Kritik'>Kritik</option>
          <option value='Anregung'>Anregung</option>
          <option value='Lob'>Lob</option>
          <option value='Allgemein'>Allgemein</option>
        </select>
        </td>
      </tr>
    <tr>
      <td valign='top' width='9'>
        <div class='morelink'>» </div>
      </td>
      <td valign='top' class='blocksatz' width='36'>E-mail: </td>
      <td valign='top' class='blocksatz' colspan='4'>
        <input type='text' name='femail' class='contentblack' size='30' maxlength='50'>
      </td>
    </tr>
    <tr>
      <td valign='top' width='9'>
        <div class='morelink'>» </div>
      </td>
      <td valign='top' class='blocksatz' width='36'>Inhalt: </td>
      <td valign='top' class='blocksatz' colspan='4'>
        <textarea name='finhalt' class='contentblack' cols='30' rows='5' wrap='PHYSICAL'></textarea>
      </td>
    </tr>
    <tr>
      <td valign='top' width='9'>
        <div class='morelink'>» </div>
      </td>
      <td valign='top' class='blocksatz' width='36'>Home: </td>
      <td valign='top' class='blocksatz' colspan='4'>
        <input type='text' name='fhome' class='contentblack' size='30' maxlength='50'>
      </td>
    </tr>
    <tr>
      <td valign='top' width='9'>
        <div class='morelink'> </div>
      </td>
      <td valign='top' class='blocksatz' width='36'> </td>
      <td valign='top' class='blocksatz' colspan='4'>
        <input type='submit' name='senden' value='senden' class='contentblack'>
        <input type='reset' name='losch' value='Löschen' class='contentblack'>
      </td>
    </tr>
    <tr>
      <td colspan='6' class='autor' height='10'>
        <div align='right'></div>
      </td>
    </tr>
    <tr>
      <td colspan='6' class='latestnews'> </td>
    </tr>
  </table>
</form>
<p align="center"><a href='buch.php' class="contentlink">Beiträge Lesen</a></p>
</body>
</html>




Bild 5.6: Aufbau der Eingabemaske innerhalb der Dreamweaver-Entwurfsansicht



Bild 5.7: Eingabemaske des Gästebuchs{PSP}2. Buch_funktionen.php

<?php

//Stammen die Daten vom Formular?
if (isset($_POST["senden"])) {

//Textfeldeingaben filtern
function daten_reiniger($inhalt) {
  if (!empty($inhalt)) {
    //HTML- und PHP-Code entfernen.
    $inhalt = strip_tags($inhalt);
    //Umlaute und Sonderzeichen in
    //HTML-Schreibweise umwandeln
    $inhalt = htmlentities($inhalt);
    //Entfernt überflüssige Zeichen
    //Anfang und Ende einer Zeichenkette
    $inhalt = trim($inhalt);
    //Backslashes entfernen
    $inhalt = stripslashes($inhalt);
  }
return $inhalt;
}

//Schreibarbeit durch Umwandlung ersparen
foreach ($_POST as $key=>$element) {
  //Dynamische Variablen erzeugen, wie g_fname, etc.
  //und die Eingaben Filtern
  ${"g_".$key} = daten_reiniger($element);
}

//Anfang – Prüfung
//Kein richtiger Name eingegeben
if(strlen($g_fname)<3){
  $error_msg="Bitte geben Sie Ihren Namen an";
}

//Kein Eintrag vorgenommen
if(strlen($g_finhalt)<3){
  $error_msg.="<br>Bitte geben Sie auch etwas in das Gästebuch ein.";
}

//Mailadresse korrekt angegeben – entsprechende Formatierung vornehmen
if(ereg("^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@([a-zA-Z0-9-]+\.)+([a-zA-Z]{2,4})$",$g_femail)){
  $format_femail="<a href=mailto:" . $g_femail . ">E-Mail</a>";
} else {
  $error_msg.="<br>Fehlerhafte E-mail!<br>";
}

//Es wurde auch eine Homepageadresse angegeben – entsprechende Formatierung vornehmen
if(ereg("^([a-zA-Z0-9-]+\.)+([a-zA-Z]{2,4})$",$g_fhome)){
  // fehlt in der Angabe der Adresse – hier ergänzen
  if(!ereg("^//",$g_fhome)){
  $g_fhome="" . $g_fhome;
}
  $g_fhome="<a href=" . $g_fhome . " target=_blank>Website</a>";
} else {
  $g_fhome="<a href=" . $g_fhome . " target=_blank>Website</a>";
}
//Ende – Prüfung

//Prüfen, ob Fehler vorgekommen sind!
if($error_msg){
echo "
<html>
<head>
<title>Gästebuch v1.0</title>
<link rel='stylesheet' href='css/main.css' type='text/css'>
</head>
<body bgcolor='#FFFFFF' text='#000000'>
<p align='center'><img src='bild/gbuchlogo.gif' width='800' height='80'></p>
<table width='300' align='center'>
  <tr>
    <td align='center' class='latestnews' colspan='3'>- FEHLER – <br>
    <p>$error_msg</p>
    <a href='javascript:history.back()' class='contentlink'>Zurück</a><br>
      Eintrag konnte nicht angelegt werden.<br>
      Versuchen Sie es bitte erneut!<br>
    </td>
  </tr>
</table>
</body>
</html>
";

} else {
$g_fdatum=date("Y-m-d H:i:s");

$eintrag="
<table width='400' align='center'>
  <tr align='left'>
    <td class='latestnews' colspan='2'> $g_fbetreff</td>
  </tr>
  <tr>
    <td colspan='2' class='autor'>
      <div align='right'>$g_fdatum</div>
    </td>
  </tr>
  <tr>
    <td valign='top' width='13'>
      <div class='morelink'>» </div>
    </td>
    <td valign='top' class='blocksatz' width='375'>". nl2br($g_finhalt) ."</td>
  </tr>
  <tr>
    <td colspan='2' class='contentblack'>
      <div align='right'>$g_fname</div>
    </td>
  </tr>
  <tr>
    <td valign='top' colspan='2'>
      <table width='100%' border='0' cellspacing='0' cellpadding='0'>
        <tr>
      <td class='autor'>
        <div align='left'>[ $format_femail ]</div>
      </td>
      <td class='autor'>
        <div align='right'>[ $g_fhome ]</div>
      </td>
      </tr>
      </table>
    </td>
  </tr>
  <tr>
    <td colspan='2' class='latestnews'> </td>
  </tr>
</table>
";

include("funktionen.php");

}

} else {
echo "
<html>
<head>
<title>Gästebuch v1.0</title>
<link rel='stylesheet' href='css/main.css' type='text/css'>
</head>
<body bgcolor='#FFFFFF' text='#000000'>
<p align='center'><img src='bild/gbuchlogo.gif' width='800' height='80'></p>
<table width='300' align='center'>
  <tr>
    <td align='center' class='latestnews' colspan='3'>- FEHLER – <br>
      Eintrag konnte nicht angelegt werden.<br>
      Versuchen Sie es bitte erneut!<br>
    <a href='buch_eintrag.php' class='contentlink'>Zurück</a></td>
  </tr>
</table>
</body>
</html>
";
}
?>
{PSP}Wie Sie sehen, werden die Daten aus den Formularelementen durch die Funktion daten_reiniger() gefiltert. Folgende Bestandteile werden gefiltert:



Bild 5.8: Fehlermeldung bei fehlerhaften Angaben

Die gefilterten Daten werden anschließend nochmals überprüft, vor allem der Inhalt der E-Mail und des Home-Formularelements wird mithilfe von regulären Ausdrücken genauer unter die Lupe genommen.

3. Funktionen.php

<?php

/////////////////////////////////////////
// Gästebuch + Reloadsperre v1.0
/////////////////////////////////////////

// 0=keine Reloadsperre, 1=Reloadsperre
$aktiv = 1;
// Zeit der Reloadsperre in Minuten
$zeit = 5;
// IP-Datei
$ipdatei = "ips.txt";
// Buchdatei
$datei = "buch_inhalt.htm";

/////////////////////////////////////////
// IP-Reloadsperre
/////////////////////////////////////////

function pruf_IP($rem_addr) {
  global $ipdatei,$zeit;
  @$ip_array = file($ipdatei);
  $reload_dat = fopen($ipdatei,"w");
  $this_time = time();
  for ($i=0; $i<count($ip_array); $i++) {
    list($ip_addr,$time_stamp) = explode("|",$ip_array[$i]);
    if ($this_time < ($time_stamp+60*$zeit)) {
      if ($ip_addr == $rem_addr) {
        $gefunden=1;
      }
      else {
        fwrite($reload_dat,"$ip_addr|$time_stamp");
      }
    }
  }
  fwrite($reload_dat,"$rem_addr|$this_time\n");
  fclose($reload_dat);
  return ($gefunden==1) ? 1 : 0;
}

/////////////////////////////////////////
// Abfrage
/////////////////////////////////////////

if (isset($_POST["senden"])) {
if (file_exists($datei) && ($aktiv==0 || ($aktiv==1 && pruf_IP($_SERVER['REMOTE_ADDR'])==0))) {
  // Falls die Datei existiert, wird sie ausgelesen und
  // die enthaltenen Daten werden durch den neuen Beitrag
  // ergänzt
  $fp=fopen($datei,"r+");
  $daten=fread($fp,filesize($datei));
  rewind($fp);
  flock($fp,2);
  fputs($fp,"$eintrag \n $daten");
  flock($fp,3);
  fclose($fp);
  include("autorespond.php");
  header("Location:buch.php");
}else if (!file_exists($datei) && ($aktiv==0 || ($aktiv==1 && pruf_IP($_SERVER['REMOTE_ADDR'])==0))) {
  // Die Datei buch_inhalt.htm existiert nicht, sie wird
  // neu angelegt und mit dem aktuellen Beitrag gespeichert.
  $fp=fopen($datei,"w");
  fputs($fp,"$eintrag \n");
  fclose($fp);
  include("autorespond.php");
  header("Location:buch.php");
} else {
  // Die Datei existiert zwar, jedoch handelt
  // es sich wahrscheinlich um den gleichen Besucher
  header("Location:buch.php");
}
} else {
echo "
<html>
<head>
<title>Gästebuch v1.0</title>
<link rel='stylesheet' href='css/main.css' type='text/css'>
</head>
<body bgcolor='#FFFFFF' text='#000000'>
<p align='center'><img src='bild/gbuchlogo.gif' width='800' height='80'></p>
<table width='300' align='center'>
  <tr>
    <td align='center' class='latestnews' colspan='3'>- FEHLER – <br>
      Eintrag konnte nicht angelegt werden.<br>
      Versuchen Sie es bitte erneut!<br>
    <a href='buch_eintrag.php' class='contentlink'>Zurück</a></td>
  </tr>
</table>
</body>
</html>
";
}

?>
{PSP}Der Inhalt dieses Skripts sollte Ihnen bereits bekannt vorkommen, es besteht nämlich größtenteils aus Bestandteilen des Besucherzählers.

4. Autorespond.php

<?php

if (isset($_POST["senden"])) {

// Mail an Webmaster
$webmaster="matthiask@flashstar.de";

$mailinhalt = "
Atomic-Book – Eintrag\n
__________________\n
Person: $g_fname\n
E-mail: $g_femail\n
WWW: $g_fhome\n
__________________\n
Betreff: $g_fbetreff\n
Kommentar:\n$g_finhalt\n
__________________\n
Zeit: $g_fdatum\n
__________________\n";

@mail($webmaster, "$g_fbetreff (von $g_fname) – Eintrag", $mailinhalt, "From: $g_femail");

// Autoresponder
$datei = "text/automail.txt";
$fp = fopen($datei, "r");
$inhalt = fread($fp,filesize($datei));
fclose($fp);

@mail("$g_femail", "Atomic-Book – Danke für Ihren Eintrag", "$inhalt\n\n","From:$webmaster");

} else {
echo "
<html>
<head>
<title>Gästebuch v1.0</title>
<link rel='stylesheet' href='css/main.css' type='text/css'>
</head>
<body bgcolor='#FFFFFF' text='#000000'>
<p align='center'><img src='bild/gbuchlogo.gif' width='800' height='80'></p>
<table width='300' align='center'>
  <tr>
    <td align='center' class='latestnews' colspan='3'>- FEHLER – <br>
      Eintrag konnte nicht angelegt werden.<br>
      Versuchen Sie es bitte erneut!<br>
    <a href='buch_eintrag.php' class='contentlink'>Zurück</a></td>
  </tr>
</table>
</body>
</html>
";
}

?>

Um die Gästebucheinträge lediglich zu betrachten, wird folgendes Skript benötigt:

5. Buch.php

<html>
<head>
<title>Gästebuch v1.0</title>
<link rel='stylesheet' href='css/main.css' type='text/css'>
</head>
<body bgcolor='#FFFFFF' text='#000000'>
<p align='center'><img src='bild/gbuchlogo.gif' width='800' height='80'></p>
<?php

$meldung="
<table width='300' align='center'>
  <tr>
  <td align='center' class='latestnews' colspan='3'><br>- LEER -<br>
  <p><a href='buch_eintrag.php' class='contentlink'>Zurück</a></p>
  </td>
  </tr>
</table>
";

if (!@include("buch_inhalt.htm")) {
  echo $meldung;
}

?>
<p align="center"><a href='buch_eintrag.php' class="contentlink">Beiträg Schreiben</a></p>
</body>
</html>

Hinweis: Sollten Sie keine Lust haben, die aufgeführten Skripts abzutippen, finden Sie sämtliche Skripts samt main.css und automail.txt auf der Buch-CD.



Bild 5.9: Ausgabe des Gästebuchs