Lösungen

Frontend-Alternativen für Datenbanklösungen 3 - PHP-Seiten als Frontend

15.11.2006
PHP und Datenbanken sind eigentlich eine perfekte Kombination, wenn es um die Verwirklichung leistungsstarker, datenbankgestützter Web- und Intranet-Anwendungen geht. Aber stimmt das auch in Bezug auf Access-Datenbanken? Der letzte Beitrag der Artikelserie zeigt, wie Sie mit PHP und Apache auf eine Access-Datenbank zugreifen.

JavaScript und andere clientseitige Skripts bergen immer ein gewisses Risiko. Zum einen können interessierte Benutzer schnell herausfinden, wie Kennwort und Pfad der Datenbank lauten. Zum anderen ist das Risiko groß, dass die Skripts durch Sicherheitssoftware und Programme, die sich dafür halten, gar nicht erst ausgeführt werden.Besser, zuverlässiger und sicherer ist daher immer eine serverseitige Variante, vor allem wenn es um leistungsfähige Internet- und Intranet-Lösungen geht.

Voraussetzungen

Um mit PHP auf eine Access-Datenbank zugreifen zu können, benötigen Sie:

Den Webserver benötigen Sie zwingend, damit überhaupt PHP-Dateien ausgeführt werden können. Welchen Webserver Sie nutzen, spielt dabei eine untergeordnete Rolle. Sie können also sowohl den IIS (Internet Information Services) als auch Apache verwenden. Darüber hinaus kommen auch viele kleinere Webserver in Frage. Egal, welchen Sie wählen: Sie müssen sicherstellen, dass dafür eine PHP-Installation mit aktiviertem ODBC-Support verfügbar ist.

PHP verwendet zum Zugriff auf Access-Datenbanken zwingend ODBC. Das heißt im Klartext: Möchten Sie eine Datenbankverbindung herstellen, die mit Sicherheit funktioniert, ist die günstigste Methode, eine System-DSN einzurichten.

Eine System-DSN setzt aber wiederum voraus, dass Sie über einen eigenen Webserver verfügen oder einen Provider haben, der Ihnen die System-DSN auf dem Server einrichtet, da sie auf dem Rechner erstellt werden muss, auf dem die Datenbank und der Webserver laufen. Verfügen Sie nur über einen Standardwebspace bei einem Provider, sollten Sie daher in Erwägung ziehen, als Datenbank doch besser auf MySQL zu setzen statt auf Access.

Damit die Access-Datenbank jedoch auch für Schreibzugriffe geöffnet werden kann, müssen Sie für das Verzeichnis, in dem sich die Datei befindet, Schreibrechte für die Internet-Benutzer festlegen. Das können Sie wahlweise beim FTPUpload der Datei mit dem Befehl chmod machen oder über die Rechtezuweisung für das Verzeichnis unter Windows 2000/XP/2003. Auch dazu benötigen Sie wieder direkten Zugriff auf die
Server.

Die Kombination aus PHP- und Access ist daher vor allem für das Intranet interessant, weil sie kostengünstiger ist als die Entwicklung von Access-Runtime-Anwendungen. Im Internet sollten Sie besser MySQL als Datenbankserver einsetzen.

Die PHP-Installation testen

Bevor Sie loslegen können, sollten Sie nach Installation des Webservers testen, ob dieser PHP ausführt und ob die benötigten PHP-Module aktiviert sind.

  1. Erstellen Sie dazu eine Textdatei mit einem Editor Ihrer Wahl. Sie können einen HTMLEditor genauso verwenden wie spezielle PHPEditoren, zur Not auch Notepad.exe.

  2. Speichern Sie die Datei als phpinfo.php ab.

  3. Fügen Sie in die Datei folgenden Code ein. Er ruft die PHP-Funktion phpinfo() auf, die wiederum Informationen zur PHP-Installation ausgibt:
    <?PHP
    phpinfo();
    ?>

  4. Kopieren Sie die PHP-Datei in das Stammverzeichnis Ihres Webservers oder ein Unterverzeichnis. Das Stammverzeichnis für XAMPP ist bei einer Standardinstallation unter Windows C:\Programme\xampp\htdocs.

  5. Starten Sie nun Ihren Browser, und geben Sie den URL der Datei ein. Haben Sie die Datei in das Unterverzeichnis bspODBCPHP kopiert, müssen Sie die Adresse http://localhost/bspODBCPHP/phpinfo.php eingeben.

  6. Ist PHP korrekt installiert und Sie haben keinen Tippfehler in der Datei gemacht, sollte nun eine blaugrau formatierte Tabelle mit allen möglichen Informationen zu PHP erscheinen. Scrollen Sie nach unten bis zum Abschnitt odbc (Bild 1).

Bild 1: Prüfen, ob ODBC aktiviert ist.

Dort sollte neben ODBC Support enabled stehen, dann ist auch ODBC aktiviert.

Aufbau der Beispieldatenbank

Die Beispieldatenbank heißt hier telefonlis-te00.mdb und besteht aus einer Tabelle tabMitarbeiter (Bild 2), in der sich schon ein paar Datensätze befinden. Die Spalte ID ist ein AutoWert-Feld und Primärschlüssel der Tabelle.

Bild 2: Aufbau der Tabelle.

Kopieren Sie die Datenbank nun in das Stammverzeichnis Ihres Webservers, beispielsweise
in das gleiche Unterverzeichnis, in dem Sie auch die Datei phpinfo.php gespeichert haben.

Die System-DSN erstellen

Bevor Sie sich an die PHP-Programmierung machen können, müssen Sie die System-DSN erstellen. Das muss auf dem Rechner erfolgen, auf dem die Datenbank liegt und der Webserver läuft. Starten Sie dazu den ODBC-Datenquellen-Manager der Systemsteuerung.

  1. In Windows XP wählen Sie dazu Start / Systemsteuerung aus, klicken auf Leistung und Wartung und dann auf Verwaltung.

  2. Führen Sie einen Doppelklick auf das Symbol Datenquellen (ODBC) aus.

  3. Aktivieren Sie die Registerkarte System-DSN, und klicken Sie auf Hinzufügen.

  4. Wählen Sie den Microsoft Access-Treiber aus, und klicken Sie auf Fertig stellen.

  5. Geben Sie in das Feld Datenquellenname den Text telefonbuchODBC ein, und klicken Sie auf Auswählen.

  6. Wählen Sie nun die Datenbank in Ihrem Verzeichnis auf dem Webserver aus, und schließen Sie dann beide Dialogfelder mit OK. Damit ist die DSN erstellt.

Datenbankverbindung aufbauen

Nun können Sie den PHP-Code erstellen, mit dem Sie eine Datenbankverbindung aufbauen.

  1. Erzeugen Sie dazu zunächst im gleichen Verzeichnis, in dem die Datei phpinfo.php liegt, eine weitere PHP-Datei mit dem Namen index.php.

  2. Erstellen Sie darin den Code für eine leere HTML-Seite (Listing 1).

  3. Fügen Sie anschließend den PHP-Code aus Listing 2 zwischen <body> und </body> ein. Er definiert den Datenquellenamen, den Benutzernamen und das Kennwort in Form von Variablen und ruft dann die PHP-Funktion odbc_connect auf. Sie baut mit Hilfe der definierten Zugangsdaten eine Datenbankverbindung auf und gibt sie zurück.

  4. Über die Variable $conn können Sie anschließend auf die Datenbankverbindung zugreifen. Führen Sie die Seite nun im Browser aus, sollte das Ergebnis wie in Bild 3 aussehen, wenn Sie keinen Fehler gemacht haben.

Bild 3: Erfolgreicher Verbindungsaufbau.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Unbenanntes Dokument</title>
</head>
<body>
</body>
</html>

<?PHP
//Datenbankverbindung aufbauen
$dsn = "telefonbuchODBC";
$tabelle = "tabMitarbeiter";
$user = "admin";
$pwd = "";
echo "<p>Datenbank-Verbindung aufbauen ...</p>";
$conn = odbc_connect($dsn,$user,$pwd);
echo "<p>... fertig!</p>";
?>

SQL-Anweisungen ausführen

Eine Datenbankverbindung alleine ist natürlich wenig sinnvoll. Sie müssen dem Benutzer natürlich die Möglichkeit bieten, in den Daten zu suchen oder sie zu ändern.

Generell gibt es dazu zwei Möglichkeiten. Sie erstellen ein reines Suchformular, oder Sie erzeugen ein Formular, in das der Benutzer SQLAnweisungen frei formulieren kann. Letzteres sollte dann natürlich nur dem Administrator zur Verfügung stehen. Beides soll aber nachfolgend gezeigt werden.

Formulare werden wie ganz normale HTML-Formulare definiert. Sie müssen also mindestens einen Submit-Button und ein weiteres Steuerelement haben. Verschieben Sie den Code aus Listing 2 ganz an den Anfang der Datei, und fügen Sie zwischen <body> und </body> zwei Formulare (Listing 3) ein.

<form method="post" action="index.php">
<input type="text" id="txtSuchbegriff" name="txtSuchbegriff" value="<? echo $str-
Suchbegriff ?>">
<input type="submit" value="senden">
</form>
<form method="post" action="index.php">
<textarea id="txtSQL" name="txtSQL" cols="50"><? echo $strSQL ?></textarea>
<input type="submit" value="senden">
</form>

Nun fehlt noch am Anfang der Seite SQL-Code, der prüft, ob Daten an die Seite übermittelt wurden, diese gegebenenfalls auswertet, die Datenbankabfrage startet und das Ergebnis dargstellt. Fügen Sie diesen Code am Anfang der Seite ein (Listing 4), bevor Sie die Datenbankverbindung herstellen. Mit der Anweisung import_request_variables rufen Sie die möglicherweise mit dem Formular übermittelten Daten ab. Sie bekommen die gleichen Namen, wie die Formularfelder mit dem Präfix "frm_", das der zweite Parameter der Funktion festlegt. Auf das Formularfeld txtSQL können Sie also mit der Variablen $frm_txtSQL zugreifen.

<?PHP
//Formulardaten lesen
import_request_variables("p","frm_");
$strSQL="";
$strSuchb="";
//Datenbankverbindungsdaten
$dsn = "telefonbuchODBC";
$tabelle = "tabMitarbeiter";
$user = "admin"; //Benutzername
$pwd = ""; //Kennwort
$erg="";
$ausgabe="";
if (@$frm_txtSuchbegriff=="")
{
$strSuchb="";
}
else
{
$strSuchb=@$frm_txtSuchbegriff;
}
if (@$frm_txtSQL=="")
{
$strSQL="";
}
else
{
$strSQL=$frm_txtSQL;
}
if (($strSQL=="") && ($strSuchb==""))
{
//keine Daten übermittelt
echo "keine Daten";
}
else
{
$conn = odbc_connect($dsn,$user,$pwd);
if ($strSQL>"")
{
//Backslashs im Code entfenren
$strSQL=str_replace ( "\\", "", $strSQL);
//SQL-Anweisung ausführen
$ausgabe=ausgeben($strSQL, $conn);
}
else
{
//Suche ausführen
$strSQL="SELECT * FROM tabMitarbeiter WHERE (Abteilung like '%" .
$strSuchb . "%') OR (Nachname like '%" .
$strSuchb . "%') OR (Vorname like '%" . $strSuchb . "%')";
$ausgabe=ausgeben($strSQL, $conn);
}
}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
...

Allerdings kann es dabei zu Fehlern kommen, wenn die Formulardaten nicht gesendet wurden, weil die Seite das erste Mal aufgerufen wurde. Daher wird zunächst für jede Variable in einer if-Verzweigung geprüft, ob Sie gleich "" ist. Damit es dabei nicht schon zu einer Fehlermeldung kommt, wird diese mit dem Zeichen @ vor der Variablen unterdrückt. Gibt es die Variablen nicht, werden die Variablen $strSuchb und $strSQL auf eine leere Zeichenfolge festgelegt, andernfalls erhalten die beiden Variablen den übermittelten Formularwert.

Anschließend können Sie prüfen, ob eine davon ungleich einer leeren Zeichenfolge ist. Falls ja, können Sie die Suche beziehungsweise die eingegebene SQL-Anweisung ausführen. Für die Suche generieren Sie dazu eine SQL-Anweisung, die die Felder Abteilung, Nachname und Vorname mit dem Like-Operator nach dem Suchbegriff durchsucht. Haben Sie die SQL-Anweisung erzeugt, übergeben Sie sie an die Funktion Ausgabe, deren Rückgabewert die Tabelle mit den Abfrageergebnissen darstellt.

Abfrageergebnisse darstellen

Nun fehlt noch die Funktion ausgeben. Ihr übergeben Sie die geöffnete Datenbankverbindung und die SQL-Anweisung. Die Funktion führt dann die SQL-Anweisung mit der Funktion odbc_exec aus. Sie gibt eine Ergebniskennung zurück, die Sie in einer Variablen (hier $erg) speichern müssen, wenn Sie das Ergebnis anzeigen möchten. Die Ergebniskennung verwenden Sie dann wieder, um alle Zeilen und Spalten in einer Schleife zu durchlaufen. Daran beteiligt sind folgende Funktionen:

odbc_num_rows ermittelt die Anzahl Zeilen,die die Abfrage zurückgegeben hat. Sie wird hier eingesetzt, damit die Ausgabe nur erfolgt, wenn die SQL-Abfrage eine Datensatzgruppe zurückgeliefert hat.

function ausgeben($strS, $dbconn)
{
$strTemp="";
$strZeile="";
$erg=odbc_exec ($dbconn, $strS );
if (odbc_num_rows($erg))
{
$spalten=odbc_num_fields($erg);
while (@odbc_fetch_row($erg))
{
for ($i=1;$i<=$spalten;$i++)
{
$strZeile .="<td>" . odbc_result ($erg,$i) . "</td>";
}
$strTemp .="<tr>" . $strZeile . "</tr>\n";
$strZeile="";
}
}
odbc_close($dbconn);
return ("<table>" . $strTemp . "</table>");
}

Mit der While-Schleife wird dann die Datensatzgruppe durchlaufen. Dabei liest die Funktion odbc_fetch_row immer die nächste Zeile aus und stellt sie zur Verfügung, sodass Sie innerhalb der Schleife mit der Funktion odbc_result auf einzelne Spalten zugreifen können. Die geben Sie über den Spaltenindex an. Die For-Schleife sorgt dafür, dass alle Spalten durchlaufen werden. Sie läuft daher von 1 bis zur Anzahl Spalten, die Sie mit der Funktion odbc_num_fields ermitteln können.

Bild 4: Ausgabe des Ergebnisses einer Abfrage.

Zum Schluss müssen Sie natürlich noch den Rückgabewert der Funktion, der in der Variablen $ausgabe gespeichert ist, an der gewünschten Stelle ausgeben. Dazu übergeben Sie die Variable einfach an die echo-Anweisung (Listing 6). Wenn Sie jetzt die Seite starten und eine SQLAnweisung eingeben, wird diese korrekt ausgeführt und unterhalb der Formulare dargestellt.

...
<?PHP
echo $ausgabe;
?>
</body>
</html>

Daten einfügen

Natürlich beschränkt sich die Kombination aus PHP und Access nicht auf den lesenden Datenbankzugriff. Schon jetzt könnte der Benutzer der Beispielanwendung durch Eingabe einer INSERT-INTO-Anweisung in das Eingabefeld für SQL-Anweisungen Daten einfügen oder mit UPDATE ändern.

Bild 5: Das Eingabeformular.

Aber sonderlich komfortabel ist das natürlich nicht. Abschließend soll daher noch einmal gezeigt werden, wie Sie mit einem recht einfachen Formular und zusätzlichem Code auch eine Eingabe von Daten ermöglichen.

Sie benötigen dazu ein Formular, das für alle Felder ein Eingabefeld enthält und einen Submit-Button hat, über den die Formulardaten gesen-det werden können. Erstellen Sie dazu die HTML-Datei in Listing 7, und speichern Sie diese als eingabe.php ab.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Dateneingabe</title>
</head>
<body>
<form method="post" action="eingabe.php">
<input type="text" id="txtID" name="txtID" readonly="readonly">
<label title="ID" for="txtID"> ID:</label><br><br>
<input type="text" id="txtAbteilung" name="txtAbteilung">
<label title="Abteilung" for="txtAbteilung"> Abteilung:</label><br><br>
<input type="text" id="txtNachname" name="txtNachname">
<label title="Nachname" for="txtNachname"> Nachname:</label><br><br>
<input type="text" id="txtVorname" name="txtVorname">
<label title="Vorname" for="txtVorname"> Vorname:</label><br><br>
<input type="text" id="txtTelefon" name="txtTelefon">
<label title="Telefon" for="txtTelefon"> Telefon:</label><br><br>
<input type="submit" value="senden">
</form>
<p><a href="index.php">Daten suchen ...</a></p>
</body>
</html>

Wenn der Benutzer Daten eingeben soll, müssen Sie die Eingabefelder des Formulars natürlich auch beschriften. Dazu gibt es hier die <label>-Elemente. Der Inhalt zwischen <label> und </label> bestimmt den Text für die Beschriftung. Der Wert des for-Attributs legt das Eingabefeld fest, für das die Beschriftung gelten soll. Mit der Position des Elements innerhalb des Quellcodes legen Sie fest, wo es standardmäßig angezeigt werden soll. Hier stehen die Beschriftungen also hinter den Eingabefeldern.

Das Attribut readonly im ersten Eingabefeld legt fest, dass hier zwar ein Eingabefeld angezeigt wird, aber keine Eingaben möglich sind. Das ist sinnvoll, weil das ID-Feld ja ein AutoWert-Feld ist. Sie können das Formular so aber auch für die Anzeige der kompletten Datensätze nutzen, wenn Sie die Anwendung erweitern möchten. Jetzt fehlt noch der entsprechende PHP-Code. Fügen Sie den Code aus Listing 8 ganz am Anfang der PHP-Datei ein.

<?PHP
//Datenbankverbindungsdaten
$dsn = "telefonbuchODBC";
$tabelle = "tabMitarbeiter";
$user = "admin"; //Benutzername
$pwd = ""; //Kennwort
$erg="";
$ausgabe="";
$strSQL="";
//Formulardaten lesen
import_request_variables("p","frm_");
//SQL-Anweisung formulieren wenn mindestens ein Feld ausgefüllt wurde
if ((@$frm_txtAbteilung>"") || (@$frm_txtNachname>"") ||
(@$frm_txtVorname>"") || (@$frm_txtTelefon>""))
{
$Werte="'" . @$frm_txtAbteilung . "','" . @$frm_txtNachname . "','"
. @$frm_txtVorname . "','" . @$frm_txtTelefon . "'";
Bild 5: Das Eingabeformular.
$strSQL="INSERT INTO tabMitarbeiter (" .
"Abteilung, Nachname, Vorname, Telefon) VALUES (" . $Werte . ");";
//SQL-Anweisung ausführen
$conn = odbc_connect($dsn,$user,$pwd);
$erg=@odbc_exec($conn, $strSQL );
if (!$erg==false)
{
$ausgabe ="<p>Daten gespeichert!</p>";
}
else
{
$ausgabe ="<p>Beim Speichern ist folgender Fehler " .
"aufgetreten: <span style='color:red'>" .
utf8_encode(odbc_errormsg($conn)) . "</span></p>";
}
}
?>

Als Erstes benötigen Sie wieder die Daten für den Datenbankzugriff, die Sie als Variablen am Anfang des Skripts definieren. Danach rufen Sie die übermittelten Formulardaten mit der Funktion import_request_variables ab. Sie sollten nun mit einer If-Verzweigung prüfen, ob mindestens ein Feld ausgefüllt wurde. Falls ja, setzen Sie die Werteliste für die INSERT-Anweisung aus den übermittelten Feldwerten zusammen. Fassen Sie diese, weil es sich um Textfelder handelt, in Hochkomma ein, und fügen Sie sie dann in die SQL-Anweisung ein, die Sie in der Variablen $strSQL speichern. Die SQL-Anweisung können Sie dann wieder mit der Funktion odbc_exec ausführen. Damit Fehlermeldungen durch falsche Eingaben nicht angezeigt werden, wird hier wieder das @-Zeichen davor gesetzt. Anschließend können Sie dann über den Rückgabewert in der Variable $erg prüfen, ob ein Fehler aufgetreten ist. In diesem Fall hat $erg den Wert false. Falls eskeinen Fehler gab, weisen Sie der Variablen $ausgabe eine entsprechende Bestätigungsmeldung zu. Ist hingegen ein Fehler aufgetreten, geben Sie sie aus. Sie wird von der Funktion odbc_errormsg geliefert. An einer beliebigen Stelle im <body>-Element der Seite können Sie dann mit <?PHP echo $ausgabe; ?> das Ergebnis der INSERT-Anweisung ausgeben.

Zusammenfassung

Wie Sie an diesem kleinen Beispiel schon sehen konnten, ist ein Datenbankzugriff auf Access-Datenbanken für PHP gar kein Problem. Zwar wurden hier die in der Praxis notwendigen Prüfungen der Eingaben auf ungültige Zeichen und dergleichen nicht vorgenommen, und auch eine Änderung der Daten ist noch nicht formulargestützt möglich, aber die Anwendung kann für die geringe Menge PHP-Code ganz schön viel. Der HTML-Code ist zwar auch nicht zu verachten, aber der kann ja heute mit jedem anständigen HTML-Editor in wenigen Minuten erstellt werden.

Darüber hinaus können Sie für größere Anwendungen mit PHP auch Code erstellen, der Ihnen die Daten über den Tabellenaufbau der benötigten Tabelle ausliest und diese Informationen nutzt, um fertige Formulare zu erzeugen. So können Sie gleichen Code für die Eingabe und Navigation von Daten in ganz verschiedenen Tabellen nutzen. Die Arbeit lohnt bei größeren Projekten in jedem Fall.

Da sowohl PHP als auch Apache kostenlos verfügbar sind, stellen Sie eine preiswerte Alternative zu kostenintensiven Entwicklungen für die Access-Runtime-Umgebung dar. Zudem lassen sie sich einfach auch auf zukünftige PHP-Versionen übertragen und müssen nicht für jede neue Access-Version neu erstellt und optimiert werden. PHP ist also eine gute und zukunftsträchtige Alternative, gerade für Intranet-Anwendungen.