Designfrage zu objektorientiertem Gästebuch

Neolity

Grünschnabel
Hallo zusammen,

bisher habe ich in PHP noch nicht objektorientiert programmiert. Da ich mit Java aber schon einige Erfahrungen sammeln konnte, wollte ich das jetzt mal ausprobieren.

Weil das Gästebuch meiner HP ziemlich unstrukturiert ist, dachte ich an ein kleines Gästebuch. Erstmal ohne viel drumherum und auf das Wesentliche konzentriert. Das heißt es soll eine Verbindung zu einer MySQL Datenbank aufgebaut werden, es sollen sich alle Einträge anzeigen lassen, man soll neue Beiträge schreiben können und eine Funktion zum löschen und eine zum verändern von bereits geschriebenen Beiträgen soll ebenfalls enthalten sein.

Aufgrund von mangelnder Erfahrung bin ich mir nicht sicher, ob ich da nicht evt. einen Denkfehler drinhabe:
Ich schreibe mir jetzt 1 Klasse mit Funktionen, die eben genau das, was ich eben beschrieben habe, machen. Auf meiner Seite "Gästebuch.php" meiner HP lege ich dann ein neues Objekt der Klasse an und rufe "showReplies()", also meine Funktion zum anzeigen aller Einträge, auf. In "neuerEintrag.php" wird ebenfalls ein Objekt von "Guestbook.php" angelegt. Beim Absenden des Formulars wird dann die Funktion "addEntry()" aufgerufen. Sollte ich mal ein kleines CMS auf die Beine stellen, dann würde ich mir da auf einer entsprechenden Seite auch wieder ein neues Objekt anlegen und könnte dann mit "deleteEntry()" oder "modifyEntry()" Einträge verändern oder löschen.

Denke ich da richtig oder macht man das mit PHP anders? Ich bin mir unsicher, ob es korrekt ist immer wieder ein neues Objekt anzulegen oder ob das auch besser geht.
Macht es Sinn die einzelnen Funktionalitäten noch stärker zu kapseln, also eine Klasse mit den Funktionen, die mit Verbindung zur Datenbank zu tun haben, etc.?

Vielen Dank! :)
 
Denke ich da richtig oder macht man das mit PHP anders?
Nein du liegst vollkommen richtig. Das stimmt genau so.

Macht es Sinn die einzelnen Funktionalitäten noch stärker zu kapseln, also eine Klasse mit den Funktionen, die mit Verbindung zur Datenbank zu tun haben, etc.?
Noch weiter zu kapseln könntest du machen (hier vielleicht auch eine Einsatz Möglichkeit für Vererbung). Allerdings muss man sich fragen, ob es Sinnvoll ist ein Gästebuch von den Funktionen her noch weiter aufzusplitten.
Denn soviele Funktionen hat ein Gästebuch ja nicht.
 
So, wie versprochen hier mal meine erste Version (Kommentare sind natürlich gerne gesehen! :) ):

PHP:
<?php
class Guestbook {
	
	private $server;             // Servername
	private $user;               // Username
	private $pass;               // Passwort
	private $dbase;              // Name der Datenbank
	private $userIp;             // IP des Users
	
	private $data = 'eintraege'; // Tabelle in der Datenbank
	
	private $conn;               // Eigenschaften der Verbindung
	
	/*
	Konstruktor, erzeugt ein neues Guestbook Objekt
	*/
	function __construct($server, $user, $pass, $dbase) {
		$this->server = $server;
		$this->user = $user;
		$this->pass = $pass;
		$this->dbase = $dbase;
		
		$this->userIp = $_SERVER['REMOTE_ADDR'];
	}
		
	/*
	Stellt die Verbindung zur Datenbank her
	*/
	function connect() {
		$this->conn = $this->setCon($this->server, $this->user, $this->pass);
		if ($this->conn)
			mysql_select_db($this->dbase, $this->conn);
		else
			echo "Verbindung konnte nicht hergestellt werden!";
	}
	
	/*
	Setzt die Variable conn auf die Werte fuer server, user und pass
	*/
	private function setCon($server, $user, $pass) {
		return @mysql_connect($server, $user, $pass);
	}
	
	/*
	Schliesst die Verbindung zur Datenbank
	*/
	function closeConn() {
		@mysql_close($dbase);
	}
	
	/*
	Zeigt alle bisher geschrieben Eintraege an
	*/
	function showReplies() {
		$sql = "SELECT * FROM $this->data ORDER BY id DESC";
		$result = mysql_query($sql, $this->conn);
		if ($result) {
			$number = mysql_num_rows($result);
			if ($number == 1)
				echo "<div id='Eintrag'> <p align=center> <b> Counter: 1 Eintrag! </b> </p> </div>";
			else
				echo "<div id='Eintrag'> <p align=center> <b> Counter: $number Einträge </b> </p> </div>";
		
			$counter = $number;
			
			while ($row = mysql_fetch_row($result)) {
				$this->showEntry($row, $counter);
				$counter--;
			}
		}
	}

	/*
	Gibt einen einzelnen Eintrag aus
	*/	
	private function showEntry($row, $counter) {
		echo "<div id='Eintrag'>";
		echo "<p> <span style='text-align: right'> <i> # </i> <b> $counter </b> </span> <br> \n";
		echo "<b> $row[1] </b> <i> schrieb am </i> <b> $row[4] </b> <i> um </i> <b> $row[5] </b> <i> Uhr: </i> <br>\n";
		if ($row[2] != '')
			echo "<i> E-Mail: </i> <b> $row[2] </b>\n";
		echo "<hr>";
		echo "<p> $row[3] </p>\n";
		echo "</p> </div> <br>\n";
	}

	/*
	Fuegt einen Eintrag hinzu
	*/
	function addEntry($Nam, $EMail, $Eingabe) {
		extract($_POST);
		$datum = date("d.m.Y");
		$zeit = date("H:i");
		$sql = "INSERT INTO eintraege(ename, email, eintrag, datum, zeit) VALUES ('$Nam', '$EMail', '$Eingabe', '$datum', '$zeit')";
		$result = mysql_query($sql, $conn);
	}
	
	/*
	Loescht einen Eintrag
	*/
	function deleteEntry($id) {
		$sql = "DELETE * FROM $this->data WHERE id=$id";
		$result = mysql_query($sql, $this->conn);
	}

	/*
	Gibt die Moeglichkeit einen Eintrag zu aendern
	*/	
	function modifyEntry() {
	}
}
?>
 
Hi, du solltest auf jeden Fall noch an der Sicherheit der ganzen Sache arbeiten, vor allem an 2 Stellen:

- showEntry:

Werte aus der Datenbank, die aus VARCHAR, TEXT oder ähnlichen Spalten kommen, solltest du grundsätzlich "escapen" bei der Ausgabe, damit evtl. eingefügter HTML Code oder ähnliches nicht verarbeitet werden kann. (XSS Anfälligkeit, einfach mal nach googlen) Beispiel für verbesserte Ausgabe:
PHP:
echo "<b> " . htmlspecialchars($row[1]) . " </b> <i> schrieb am </i> <b> " . htmlspecialchars($row[4]) . " </b> <i> um </i> <b> " . htmlspecialchars($row[5]) . " </b> <i> Uhr: </i> <br>\n";

-addEntry:

Beim einfügen von Daten in eine Datenbank sollte grundsätzlich eine Validierung / Überprüfung der Daten erfolgen und evtl. eine Filterung, da sonst sehr leicht gefährliche Eingaben gemacht werden können. (Stichwort: SQL-Injection und co.)

Beispiel für Verbesserungen:
PHP:
    function addEntry($Nam, $EMail, $Eingabe) {
        extract($_POST);

        // Hier erstmal die Daten prüfen und evtl. Fehler ausgeben, z.B. schauen, ob ein Name angegeben ist usw.

        // Filtern der Daten:
        $name = mysql_real_escape_string($Nam, $this->conn);
        $email = mysql_real_escape_string($EMail, $this->conn);
        $eingabe = mysql_real_escape_string(strip_tags($Eingabe), $this->conn);
        $datum = date("d.m.Y");
        $zeit = date("H:i");

        // Einfügen der Daten:
        $sql = "INSERT INTO `eintraege` (`ename`, `email`, `eintrag`, `datum`, `zeit`) VALUES ('$name', '$email', '$eingabe', '$datum', '$zeit')";
        $result = mysql_query($sql, $this->conn);
    }
P.S:

Bei allen mysql_query() Aufrufen muss, in deinem Fall, der 2. Parameter nicht $conn sondern $this->conn sein, da du ja die Verbindung in der Klasse speicherst. Achja, und zum testen am besten folgendes ganz am Anfang deines Scripts benutzen:
PHP:
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', true);
 
Zuletzt bearbeitet:
Zurück