Zielsetzung:
Auf einer Webseite sollen sich Personen eintragen können und sehen, ob sie sich eingetragen haben.
Gebraucht wird:
-  ein Speicherort für die Namen
Die Liste sollte enthalten:
-  Vornamen
 -  Name
 -  Wohnort
 -  Webseite
 -  Mailadresse
 -  Personen Beschreibung 
 -  Dienstzeit
 -  Dienstgrad
 -  Dienststellung
 -  Einheit in der Gedient wurde
 -  Schiff - Bordnummer
 -  Schiff - Projekt
 
 -  ein Script, welches das Eintragen der Daten übernimmt und diese anzeigen kann.
 
Mögliche Probleme:
Es werden Persönliche Daten eingetragen, die nicht für jeden einsehbar sein sollten (mit Name Anschrift und Email-Adresse kann man schon einigen Unsinn im Netz anstellen). Aus diesem Grund sollte der Zugang begrenzt werden. Ein Passwort, das der Nutzer bei der ersten Anmeldung eingibt würde schon helfen. Da das hier nirgendwo angesprochen wurde werde ich auch kein Passwort vorsehen.
Je nach Umfang der Daten kann es günstig sein ein Datenbank zu benutzen um diese zu speichern. Wenn Daten nur eingetragen aber nicht gelöscht oder geändert werden, so kann man auch ein einfache Datei nutzen, um die Daten zu speichern.
Ich gehe davon aus, dass es nur wenige Nutzer geben wird und das keine Änderungen vorgenommen werden sollen. Weshalb man problemlos auf eine Datei setzen kann.
Was soll das Script können:
-  es soll die Daten Annehmen und speichern
 -  es soll die gespeicherten Daten anzeigen können
 
Daraus folgt das zwei grundsätzliche Funktionen gebraucht werden:
-  zeige_personen
-  die Anzeige soll alphabetisch sein
 -  Von einer Zusammenfassung soll man zu der ausführlichen Ausgaben springen können
 -  Die Ausführliche Liste soll alle gespeicherten Informationen in einer leiht Lesbaren Form enthalten
 
 -  speicher_person
-  Die Eingaben sollen geprüft werden.
-  ob die Eingaben vollständig sind
 -  ob die Person schon in der Liste existiert
 
 -  Die Eingaben sollen gespeichert werden
 
 
Beginnen werde ich mit der Funktion 
speicher_person:
An sie über geben werden muss
-  Vornamen
 -  Name
 -  Wohnort
 -  Webseite
 -  Mailadresse
 -  Personen Beschreibung 
 -  Dienstzeit
 -  Dienstgrad
 -  Dienststellung
 -  Einheit in der Gedient wurde
 -  Schiff - Bordnummer
 -  Schiff - Projekt
 -  Die Datei in der gespeichert werden soll
 
Geprüft werden muss ob folgende Angaben existieren:
Vornamen, Name, Wohnort, Mailadresse
Wenn eine davon nicht existiert, soll die Eingabemaske mit einer Warnung angezeigt werden.
Wenn die Kombination aus Vornamen, Name oder die Mailadresse in der Datei schon existiert, so soll die Eingabemaske mit einer Warnung angezeigt werden.
Wenn die Prüfung erfolgreich war sollen die Daten gespeichert werden und die Liste mit den Namen angezeigt werden.
Nun ist schon ersichtlich, dass eine weitere Funktion gebraucht wird um die Eingabemaske zusammen mit einer Möglichen Meldung anzuzeigen. Ich werde diese Funktion 
zeige_maske nennen.
zeige_maske hat als einzigen Parameter eine Mögliche Meldung.
Machen wie Funktion 
speicher_person etwas genauer:
-  lese Parameter 
-  Vornamen
 -  Name
 -  Wohnort
 -  Webseite
 -  Mailadresse
 -  Personen Beschreibung 
 -  Dienstzeit
 -  Dienstgrad
 -  Dienststellung
 -  Einheit in der Gedient wurde
 -  Schiff - Bordnummer
 -  Schiff - Projekt
 -  Die Datei in der gespeichert werden soll
 
 -  prüfe ob
-  Vornamen nicht leer
 -  Name nicht leer
 -  Wohnort nicht leer
 -  wenn Mailadresse vorhanden prüfe ob es eine gültige ist
Wenn eine Prüfung fehlschlägt so rufe die Funktion zeige_maske mit der Meldung "Die Eingabe ist unvollständig!" auf 
 -  lese alle Daten 
 -  prüfe ob
-  Mailadresse oder
 -  Name und Vornamen schon vorkommen
 
Wenn das Fehlschlägt rufe die Funktion zeige_maske mit der Meldung "Diese Daten wurden schon eingetragen!" auf. -  Hänge die neuen Daten an die Alten an
 -  rufe zeige_personen auf
 
Zu 
zeige_personen
-  Hole die Datei
 -  lese die Daten aus der Datei
 -  Sortiere die Daten Alphabetisch nach Name und Vornamen
 -  Gehe die Daten durch und Erzeuge mit Name und Voraname eine HTML-Liste
 -  gib die Liste aus
 -  Gehe die Daten durch und erzeuge eine HTML-Liste mit allen Daten
 -  gib das HTML aus
 
Man kann schon sehen, dass die Datei mehrfach gelesen wird. Es wäre hier günstig Zu betrachten was alles mit der Datei gemacht wird.
Die Datei wird gelesen, durchsucht und es werden Daten angehängt.
So wie es jetzt aussieht wird die Datei zweimal gelesen, einmal wenn die Eingaben geprüft werden und ein anderes mal wenn die Daten Ausgeben werden.
Um das zu verhindern sollte man Die Dateizugriffe kapseln und die Zugriffe auf die Daten zu abstrahieren.
Hier bietet sich ein Objekt an, das es erlaubt:
-  einzelne Datensätze zu holen.
 -  In den Datensätzen zu suchen.
 -  Datensätze hinzu zu fügen.
 
das hat auch weiterhin den Vorteil, das man Das Objekt intern wahlweise mit DB-Zugriffen oder mit Datei-Zugriffen realisieren kann.
Ich werde es 
PersonenDB nennen.
[EDIT]Nicht vorhandenen Gedankengänge ergänzt
Es werden Methoden gebraucht, mit der man Die Daten sortieren lesen, suchen und schreiben kann.
Es wird also so etwas wie ein 
read sort get_by get_all und 
add gebraucht.
Mit 
read sollen die Daten geladen werden. Mit 
sort sollen die Daten im Speicher sortiert werden, sodass sie bei der Ausgabe durch 
get_by und 
get_all sortiert sind. An 
add sollen alle Daten übergeben werden, die für eine Person wichtig sind. Da bietet sich ein Hash, als Übergabeparameter an, da es viele Parameter sind und eine Sortierung nicht nötig. Das bedeutet aber dass die Klasse alle Erlaubten ParemeterNamen kennen muss, damit das Objekt sie in der richtigen Reihenfolge in die Datei schreiben kann und prüfen kann welche Parameter vorhanden sind. Da bei der Prüfung auch Fehler auftreten können ist es günstig diese im Objekt zu speichern und über eine Methode abfragbar zu machen. Als Mame der Methode bietet sich 
error an.
Fasse ich mal zusammen:
gebraucht werden:
Klassenparameter:
-  Liste aller Schlüssel die eine Person haben kann
 -  Liste der Zwingend nötigen Parameter
 
Methoden:
-  read
 -  add
 -  sort
 -  get_by
 -  get_all
 -  error
 
Nun werden noch die Objekt-Parameter gebraucht.
Das wäre zum einen eine Liste mit allen Personen, ein Parameter um die Fehler zu speichern und einer um den Dateinamen vor zu halten.
Will man nun beginnen die Methode 
read zu schreiben muss man sich Gedanken über das Dateiformat machen. Das einfachste ist ein CSV-Artiges Format zu nutzen. Dar Nachteil dabei ist, dass ASCII-Zeichen als Feldtrenner genutzt werden, die auch in den Feldern vorkommen können. Man kann sie entweder verbieten, oder ersetzen. Ich werde mich für das ersetzen entscheiden. Dazu muss ich alle Zeichen die Feldtrenner oder Zeilentrenner sind durch ein Folge von Zeichen ersetzen, die diese repräsentiert das wird im allgemeinen "entwerten" oder "quoten" genannt. Wenn ich als Feldtrenner ";" und als Zeilentrenner "\n" (bzw "\x0A") Benutzte, muss ich diese In den Feldern entwerten. Dazu nehme ich den ASCII wert der s zeichen als dreistellige zahl und setze ein % davor. das bedeutet auch dass % entwertet werden muss. Es wird eine Methode gebraucht die Alle Zeichen entwertet und eine die alle Entwertungen rückgängig macht.
Quotequote
 und 
unquote Das Lesen gestaltet sich nun wie folgt:
read:
-  öffne die Datei
 -  lese sie zyklisch bis zum nächsten Zeilentrenner
 -  trenne sie an den Feldtrennern
 -  mach die Entwertung der geschützten Zeichen rückgängig
 -  Speicher die werte im Objekt
 
das schreiben:
add
-  teste ob alle Paramter vorhanden
 -  teste ob die Person schon eingetragen ist (hierzu bietet sie eine Methode exists an)
 -  öffne die Datei wenn nötig
 -  entwerte die geschützten zeichen
 -  Erzeuge einen Dateieintrag durch zusammenfügen der Felder
 -  hänge den Eintrag an die Datei an
 
sort
-  sortiere die liste nach Nachnamen, Vornamen und Adresse
 
get_by
-  filtere alle Einträge aus der Liste der Personen, die zu dem Feld die den richtigen Wert haben
 
Wenn man nun weiter konsequent weitermacht kann man zu einer Klasse ähnlich der die unten gezeigt wird kommen.
[/EDIT]
Jetzt wäre es nötig Die Klasse zum Objekt zu gestalten. Das kürze ich ab und springen direkt zur Implementation dieser zentralen Funktionalität:
PersonenDB.pm:
more (53.1kb)
[EDIT]Gedanken ergänzt:
Wie man sehen kann ist die gesamte Prüfung in den Code für die DB gewandert. Dadurch entfallen sämtliche Prüfungen im Script. Diese muss nur noch prüfen, ob eine Aktion erfolgreich war. Außerdem mache ich einen "Lock" auf die Datei, um Kornkurierende Schreib/Lesezugriffe zu kontrollieren. Das verhindert zerstörte Einträge wenn zwei Personen sich gleichzeitig eintragen wollen.
[/EDIT]
Die Klasse sollte man auch gleich testen:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
 
use strict;
use warnings;
use PersonenDB;
use Data::Dumper;
my $db = PersonenDB->new('test.dat');
$db->add({
    vorname        => 'Test',
    nachname       => 'Tester',
    address        => 'TestStr 1',
    website        => 'www.test.de/test2',
    email          => 'mail@test.de',
    dienstzeit     => 100,
    dienstgrad     => '1',
    dienststellung => '1965.1.12',
    einheit        => 'rable',
    nummer         => 837,
    typ            => 4,
    person         => 'das ist nur ein test!',
  }) || print "ERROR:".$db->error()."\n";
$db->add({
    vorname        => 'Toto',
    nachname       => 'Testerito',
    address        => 'TestStr 22',
    website        => 'www.test.de/test1',
    email          => 'mail1@test.de',
    dienstzeit     => 100,
    dienstgrad     => '2',
    dienststellung => '1965.1.12',
    einheit        => 'blub',
    nummer         => 837,
    typ            => 2,
    person         => 'das ist nur ein test!',
  }) || print "ERROR:".$db->error()."\n";
$db->add({
    vorname        => 'Tranta',
    nachname       => 'Tester',
    address        => 'TestStr 1',
    website        => 'www.test.de/test3',
    email          => 'mail2@test.de',
    dienstzeit     => 100,
    dienstgrad     => '3',
    dienststellung => '1923',
    einheit        => 'bla',
    nummer         => 11234,
    typ            => 1,
    person         => 'das ist nur ein test!',
  }) || print "ERROR:".$db->error()."\n";
$db->add({
    vorname        => 'Karl',
    nachname       => 'Boratis',
    address        => "Rabenweg 19293\n12345 Braurig",
    website        => 'www.test.de/test3',
    email          => 'mail3@test.de',
    dienstzeit     => 100,
    dienstgrad     => '4',
    dienststellung => "2.11.1968",
    einheit        => 'bla',
    nummer         => 4,
    typ            => 4,
    person         => 'das ist nur ein test!',
  }) || print "ERROR:".$db->error()."\n";
$db->add({
    vorname        => 'Henry',
    nachname       => 'Boratis',
    address        => "Rabenweg 19293\n12345 Braurig",
    website        => 'www.test.de/test4',
    email          => 'xxx???&test.??',
    dienstzeit     => 100,
    dienstgrad     => '4',
    einheit        => 'luba',
    nummer         => 55,
    typ            => 3,
    person         => 'das ist nur ein test!',
  }) || print "ERROR:".$db->error()."\n";
print Dumper([$db->all()]);
 
 
Damit wäre die Datenbank fertig. Nun wird es Zeit sich über das HTML Gedanken zu machen. Es ist günstig HTML und Code zu trennen, das erleichtert nicht nur Übersichtlichkeit es erleichtert auch die Pflege und verhindert Fehler.
Ich werte 
HTML::Template::Compiled nutzen.
Zuerst die Webseite zum eintragen der Personen:
input.tmpl
more (37.4kb)
nun noch das HTML für die Liste:
show.tmpl
more (30.5kb)
Und nun zum eigentlichen Code.
durch die Verwendung einer Klasse, das die Dateizugriffe kapselt, verändern sich die Parameter, die an die Funktionen übergeben werden und die Abläufe ein wenig. Im großen und ganzen bleiben die Funktionalitäten aber erhalten.
Da man sich schon Geadnken über den Aufbau gemacht hat, ist die Implementation nicht mehr so schwehr. Durch die saubere Abtrennung der Datenhaltung und dem HTML ist der Code sehr übersichtlich und ist nur die Verbindung zwischen den Daten und dem HTML
liste.pl
more (27.4kb)
Es ist alles nicht so schwehr.
Last edited: 2011-07-18 14:22:16 +0200 (CEST)