Photoshop
Cinema 4d
Fotografie
Weitere Grafiksoftware
HTML / CSS
JavaScript
Flash
PHP
Webserver
Sonstige
Anwesenheitsliste in PHP (PHP Tutorial)
Tutorial erstellt von submarine in >= PHP 4, letzte Änderung am 02.11.2009Vorüberlegungen
In quasi jedem Verein oder in jeder Mannschaft wird eine Anwesenheitsliste geführt.
Diese besteht meist aus den Mitgliedern, den Terminen und den Kürzeln (z.B. x | -). Um den Mitgliedern diesen Vorgang zu vereinfachen kann diese Liste bequem online im internen Bereich einer Website geführt werden.
Voraussetzungen
Um dieses System sinnvoll zu betreiben braucht ihr einen passwortgeschützten Bereich für die Mitglieder, einen PHP 5-fähigen Server und eine MySQL Datenbank.
Außerdem ist es wichtig, dass ihr die ID (Identifikationsnummer) des Benutzers, der gerade online ist, entweder über die URL oder über eine Session als Variable "user" übergebt, damit ein Benutzer auch nur seine eigenen Status ändern kann.
Datenbankstruktur
Wie schon angesprochen besteht die Anwesenheitsliste aus den Terminen, den Mitgliedern und den Status. Die Tabellen "Mitglieder" sowie "Termine" sollten bereits bestehen. Diese sollten mindestens folgende Felder in gleicher oder ähnlicher Weise beinhalten:
Mitglieder:
- id (z.B. vom Typ INT)
- name (VARCHAR)
Termine:
- id (INT)
- date (DATETIME)
Nun brauchen wir noch eine dritte Tabelle für die Daten. Sie sollte wie folgt angelegt werden:
Code:
CREATE TABLE `Anwesenheit` (
`tid` INT(11) NOT NULL,
`mid` INT(11) NOT NULL,
`presence` INT(11) NOT NULL
);
Das Feld `tid` muss vom selben Typ sein, wie das Feld `id` in "Termine". Genauso muss mit dem Feld `mid` verfahren werden.
Die Tabelle `Anwesenheit` verknüpft die Tabellen `Mitglieder` und `Terminen` miteinander. Das bedeutet, dass ihre Datensätze einen Verweis auf Datensätze aus den beiden Tabellen beeinhaltet: `Anwesenheit.tid` -> `Termine.id`; `Anwesenheit.mid` -> `Mitglieder.id`. Es wird also pro Datum und Mitglied ein Eintrag erstellt.
Code:
tid | mid | presence
1 | 1 | 0
1 | 2 | 0
2 | 1 | 0
2 | 2 | 0
Aufbau der Anwesenheitsliste
Nachdem wir jetzt unsere Datenbank soweit vorbereitet haben, können wir damit beginnen, unsere Liste aufzubauen. Wir nutzen hierbei eine Tabelle, weil hiermit leicht ein dynamisches und übersichtliches Layout erzeugt werden kann.
Grundstruktur
Als erstes definieren wir eine Funktion zum Erstellen einer Tabelle.
Code:
function echoTable() {
echo '<table id="alist_table">';
create_titlerow();
get_maindata();
echo '</table>';
}
Jetzt generieren wir unsere Titelzeile, die die Namen der Mitglieder enthält. In der while-Schleife wird jeder Name einzeln ausgelesen und in eine Zelle geschrieben.
Code:
function create_titlerow() {
echo '<tr class="titlerow">';
echo '<td>Name/Datum</td>';
$result_name = mysql_query('SELECT DISTINCT(name) FROM `Anwesenheit`, `Mitglieder` WHERE `mid` = `id` ORDER BY `name`');
while($row_name = mysql_fetch_array($result_name)) {
echo '<td>'.$row_name['name'].'</td>';
}
echo '</tr>';
}
Nun wollen wir natürlich auch die Termine und die Status der Mitlieder zu den einzelnen Daten ausgeben. Als erstes definieren wir einen Query, der die ID, das Datum und dessen deutsche Formatierung ausliest. Danach kommt die Funktion str_replace() zum Einsatz, um aus den englischen Wochentagen die Deutschen zu machen.
Jetzt kommt der interessante Teil: Da die Mitglieder später ihren Status ja auch ändern können sollen, müssen wir zwei Arten der Ausgabe definieren. Zum Ersten die "normale" Ausgabe, in der der Status einfach ausgegeben wird. Hierfür nutzen wir später die Funktion create_datarow_passive().
Wollen die Benutzer einen Status ändern, geben wir ihnen die Möglichkeit, indem wir ihnen Dropdownlisten zur Verfügung stellen. Dafür nutzen wir dann die Funktion create_datarow_active(). Diese wird aber nur dann verwendet, wenn der Modus "edit" und die Termin-ID gleich der aktuellen (in der Schleife wird ja immer nur ein Termin ausgegeben) ist. Den Modus und die Termin-ID schicken wir später über die URL.
Code:
function get_maindata() {
global $mode, $tid;
$result_date = mysql_query('SELECT `id`, `date`, DATE_FORMAT(`date`, "%W. %D.%m.%Y") AS `germ_date` FROM `Termine` ORDER BY `date`');
while($row_date = mysql_fetch_array($result_date)) {
$date_id = $row_date['id'];
$date_origin = $row_date['date'];
$date_new = array('So','Mo','Di','Mi','Do','Fr','Sa');
$date_old = array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
$date_clear = str_replace($date_old, $date_new, $row_date['germ_date']);
if($mode == 'edit' && $tid == $date_id) {
create_datarow_active($date_id, $date_clear, $date_origin);
}
else {
create_datarow_passive($date_id, $date_clear, $date_origin);
}
}
}
Statusausgabe
Jetzt endlich geben wir das erste mal Daten aus. Das ist eigentlich recht einfach:
Als erstes geben wir eine Tabellenzeile aus, die als erste Zelle das deutsche Datum ($date_clear) enthält. Die nächsten Zellen enthalten die Status:
Wir lesen alles aus den Tabellen `Anwesenheit` und `Mitglieder` aus, verwenden hierbei die WHERE-Klausel um die `mid` aus `Anwesenheit` mit der `id` aus `Mitgliedern` zu verknüpfen.
Gleichzeitig wollen wir aber nur die Daten eines Termins auslesen, der in der Funktion get_maindata() in der Schleife festgelegt wird.
Code:
function create_datarow_passive($date_id, $date_clear, $date_origin) {
echo '<tr class="datarow">';
echo '<td class="datecell">'.$date_clear.'</td>'; //Ausgabe des Datums
$result_presence = mysql_query('SELECT * FROM `Anwesenheit`, `Mitglieder` WHERE `mid` = `ID` AND `tid` = "'.$date_id.'" ORDER BY `name`');
while($row_presence = mysql_fetch_array($result_presence)) {
echo '<td>';
$old = array('0', '1'); //Ersetzen der Ziffern aus der DB...
$new = array('anwesend', 'entschuldigt'); //...mit den Stati zum lesen
echo str_replace($old, $new, $row_presence['presence']);
echo '</td>';
}
echo '<td> <a href="DEINE_URL_VOM_INTERNEN_BEREICH?user='.$activeUser.'&mode=edit&tid='.$date_id.'">[ändern]</a></td>';
echo '</tr>';
}
Das sollte jetzt ungefähr so aussehen:

Die etwas kompliziertere Ausgabe von Daten - der aktive Modus. Hier geben wir nicht wie in der vorherigen Funktion die Status einfach aus, sondern ermöglichen es dem Benutzer, seine Status zu ändern.
Step by step:
[list]
Am Ende fügen wir noch die inputs hinzu - hidden-Inputs für das bearbeitete Datum, den aktiven Benutzer und eine Kontrolle; einen Button zum Senden.
Code:
function create_datarow_active($date_id, $date_clear, $date_origin) {
global $activeUser;
echo '<form name="editDate['.$date_id.']" action="URL_VOM_ÄNDERUNGS-SCRIPT" method="post">';
echo '<tr id="date_'.$date_id.'">';
echo '<td class="datecell">'.$date_clear.'</td>';
$result_presence = mysql_query('SELECT * FROM `Anwesenheit`, `Mitglieder` WHERE `mid` = `id` AND `tid` = "'.$date_id.'" ORDER BY `name`');
while($row_presence = mysql_fetch_array($result_presence)) {
$user_id = $row_presence['id'];
if($user_id == $activeUser){
echo '<td>';
echo '<select name="date_single['.$row_presence['mid'].']" >';
switch($row_presence['presence']) {
case '0': option(0, 1); break;
case '1': option(1, 0); break;
}
echo '</select>';
echo '</td>';
}
else {
$old = array('0', '1'); //Ersetzen der Ziffern aus der DB...
$new = array('anwesend', 'entschuldigt'); //...mit den Status zum lesen
echo '<td>'. str_replace($old, $new, $row_presence['presence']).'</td>';
}
}
echo '<td>';
echo '<input type="hidden" name="tid" value="'.$date_id.'" />';
echo '<input type="hidden" name="user" value="'.$activeUser.'" />';
echo '<input type="hidden" name="check" value="true" />';
echo '<input type="submit" value="speichern" />';
echo '</td>';
echo '</tr>';
echo '</form>';
}
Die Funktion option() steuert die Ausgabe der Auswahlmöglichkeiten. In der vorigen Funktion haben wir mit dem switch festgelegt, welcher Status aktiv und welcher passiv ist. Das greifen wir hier wieder auf:
Der aktive Status ist bereits ausgewählt, der passive kann ausgewählt werden.
Code:
function option($active, $passive) {
$old = array('0', '1');
$new = array('anwesend', 'entschuldigt');
$echo_option = '<option selected="selected" value="'.$active.'" >'.$active.'</option>';
$echo_option .= '<option value="'.$passive.'">'.$passive.'</option>';
echo str_replace($old, $new, $echo_option);
}
Jetzt sollte die Tabelle wie folgt aussehen:

Nun einmal der komplette Code. Am Anfang hab' ich noch die nötigen kleinen Sachen hinzugeschrieben, wie die Datenbankverbindung und die $_GETs für die Variablen aus der URL. Auch muss die Funktion echoTable() natürlich am Ende aufgerufen werden.
Code:
<?php
include('dbconnect.php');
$activeUser = $_GET['user'];
$tid = $_GET['tid'];
$mode = $_GET['mode'];
function echoTable() {
echo '<table id="alist_table">';
create_titlerow();
get_maindata();
echo '</table>';
}
function create_titlerow() {
echo '<tr class="titlerow">';
echo '<td>Name/Datum</td>';
$result_name = mysql_query('SELECT DISTINCT(name) FROM `Anwesenheit`, `Mitglieder` WHERE `mid` = `id` ORDER BY `name`');
while($row_name = mysql_fetch_array($result_name)){
echo '<td>'.$row_name['name'].'</td>';
}
echo '</tr>';
}
function get_maindata() {
global $mode, $tid;
$result_date = mysql_query('SELECT `id`, `date`, DATE_FORMAT(`date`, "%W. %d.%m.%Y") AS `germ_date` FROM `Termine` ORDER BY `date`');
while($row_date = mysql_fetch_array($result_date)) {
$date_id = $row_date['id'];
$date_origin = $row_date['date'];
$date_new = array('So','Mo','Di','Mi','Do','Fr','Sa');
$date_old = array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
$date_clear = str_replace($date_old, $date_new, $row_date['germ_date']);
if($mode == 'edit' && $tid == $date_id) {
create_datarow_active($date_id, $date_clear, $date_origin);
}
else {
create_datarow_passive($date_id, $date_clear, $date_origin);
}
}
}
function create_datarow_passive($date_id, $date_clear, $date_origin){
echo '<tr class="datarow" >';
echo '<td class="datecell">'.$date_clear.'</td>'; //Ausgabe des Datums
$result_presence = mysql_query('SELECT * FROM `Anwesenheit`, `Mitglieder` WHERE `mid` = `id` AND `tid` = "'.$date_id."' ORDER BY `name`');
while($row_presence = mysql_fetch_array($result_presence)) {
echo '<td>';
$old = array('0', '1'); //Ersetzen der Ziffern aus der DB...
$new = array('anwesend', 'entschuldigt'); //...mit den Status zum Lesen
echo str_replace($old, $new, $row_presence['presence']);
echo '</td>';
}
echo '<td> <a href="DEINE_URL_VOM_INTERNEN_BEREICH?user='.$activeUser.'&mode=edit&tid='.$date_id.'">[ändern]</a></td>';
echo '</tr>';
}
function create_datarow_active($date_id, $date_clear, $date_origin) {
global $activeUser;
echo '<form name="editDate['.$date_id.']" action="URL_VOM_ÄNDERUNGS-SCRIPT" method="post">';
echo '<tr id="date_'.$date_id.'">';
echo '<td class="datecell">'.$date_clear.'</td>';
$result_presence = mysql_query('SELECT * FROM `Anwesenheit`, `Mitglieder` WHERE `mid` = `id` AND `tid` = "'.$date_id.'" ORDER BY `name`');
while($row_presence = mysql_fetch_array($result_presence)) {
$user_id = $row_presence['id'];
if($user_id == $activeUser) {
echo '<td>';
echo '<select name="date_single['.$row_presence2['uid'].']">';
switch($row_presence['presence']) {
case '0': option(0, 1); break;
case '1': option(1, 0); break;
}
echo '</select>';
echo '</td>';
}
else {
$old = array('0', '1'); //Ersetzen der Ziffern aus der DB...
$new = array('anwesend', 'entschuldigt'); //...mit den Status zum Lesen
echo '<td>'. str_replace($old, $new, $row_presence['presence']).'</td>';
}
}
echo '<td>';
echo '<input type="hidden" name="tid" value="'.$date_id.'" />';
echo '<input type="hidden" name="user" value="'.$activeUser.'" />';
echo '<input type="hidden" name="check" value="true" />';
echo '<input type="submit" value="speichern" />';
echo '</td>';
echo '</tr>';
echo '</form>';
}
function option($active, $passive) {
$old = array('0', '1');
$new = array('anwesend', 'entschuldigt');
$echo_option = '<option selected="selected" value="'.$active.'" >'.$active.'</option>';
$echo_option .= '<option value="'.$passive.'">'.$passive.'</option>';
echo str_replace($old, $new, $echo_option);
}
echoTable();
?>
Damit sind wir mit der Anwesenheitsliste auch schon fertig :)
Aber es fehlt noch das Script zum Ändern der Daten - weiter geht's...
Das Formular ruft diese Datei auf (bitte sowohl in der Datei für die Liste als auch hier auf den selben Namen achten), welche die Daten empfängt, auswertet und in die Datenbank schreibt. Danach wird der Benutzer wieder zurück geleitet.
Code:
<?php
include('dbconnect.php');
$get_tid = $_GET'tid'];
$activeUser = $_GET['user'];
$get_presence = $_GET['date_single'];
$old = array('anwesend', 'entschuldigt');
$new = array('0', '1');
$get_presence = str_replace($old, $new, $get_presence);
if($_GET['check']) {
foreach($get_presence as $mid => $presence) {
mysql_query('UPDATE `Anwesenheit`
SET `presence` = "'.$presence.'"
WHERE `tid` = '$get_tid' AND mid = "'.$mid.'"');
}
}
header ('Location: URL_DES_INTERNEN_BEREICHS?user='.$activeUser);
?>
HINWEIS: Bei jedem neuen Termin, der in die Datenbank eingefügt wird, muss darauf geachtet werden, dass auch die Tabelle `Anwesenheit` ergänzt wird!
Dazu muss für jedes Mitglied ein neuer Eintrag mit der ID des neuen Datums, seiner ID und einem Standardwert für die Spalte `presence` erstellt werden. Das könnte so aussehen:
Code:
<?php
$result_user = mysql_query('SELECT * FROM `Mitglieder`');
while($row_user = mysql_fetch_array($result_user)) {
$user_id = $row_user['id'];
mysql_query('INSERT INTO `Anwesenheit`
SET
`tid` = "'.$id_date.'",
`mid` = "'.$id_user.'",
`presence` = "0"');
}
?>
Nun sollte die Anwesenheitsliste voll funktionsfähig sein, bei Fragen einfach im Forum melden.
Viel Spaß!
>> Allgemeine Fragen oder Probleme mit dem Tutorial? Hier gehts zum Forum!