2D1522 Datorteknik och -kommunikation
2D2051 Databasteknik och datorkommunikation
Laboration 3:
Webprogrammering med databaser
Förberedelser
Det hjälper om man studerat föreläsningsanteckningarna och
boken. Det är en fördel att ha boken till hands, men det går
att klara labben ändå. Du bör åtminstone ha föreläsningsanteckningarna
om webprogrammering till hands.
PHP-manualen rekommenderas.
Redovisning
Laborationen utföres i grupper om 2 personer (eller ensamma om ni vill och
det finns plats).
Redovisning sker muntligt vid labbtillfälle eller senare efter överenskommelse.
Observera att de som ska göra laboration 4 (kurs 2D2051) ska redovisa
laborationerna 3 och 4 tillsammans.
Kökslista
I denna laboration ska du få göra ett litet system
för att administrera köksansvarighets-listor. Systemet ska baseras
på en databas. Den synliga delen av systemet är en websida som ser ut ungefär
så här:
Kökslista
Veckonr | Namn |
25 | Inge Frick |
33 | Jan Banan |
35 | Kalle Kula |
Sätt in ny person
Websidan har följande innehåll:
- En tabell som visar köksansvariga från den aktuella veckan
och framåt resten av året.
- En knapp (i realiteten ett formulär) som mailar till köksansvarige
och påminner om att denne ska köpa mjölk osv
- Ett formulär i vilket man kan ange ett veckonummer och
välja ett namn från en meny av personer. Den valda personen ska
vara köksansvarig den angivna veckan. Om man väljer ett veckonummer
som redan finns i listan over köksansvariga, så ska den ansvarige
den angivna veckan ändras.
- Ett formulär från vilket man kan välja ett namn och en
mail-adress som stoppas in listan över personer som kan väljas
som köksansvarig. Om en person som redan finns anges så ska endast
en ny mail-adress stoppas in.
Kommentarer
OBS! Läs detta nogrant
Denna websida skrivs som ett php-skript med understöd av en databas och
en fil av php-funktioner som hanterar databasen.
Webbsidan innehåller tre 'klick'bara knappar, var och en är en
'submit'knapp i ett separat formulär. (knappen
"Skicka brev till köksansvarig denna vecka" ligger i ett formulär
som bara består av denna knapp).
Då man 'klickar' på en knapp
ska datorpost skickas resp databasen uppdateras och samma webbsida
ska visas igen men nu eventuellt med en uppdaterad lista över
köksansvariga.
Detta kan göras på två sätt:
- Anges ingen 'action' i form-elementet (starten av formuläret) kommer
webbsidans php-skript att anropas igen med de aktulla formulärvariablerna
medskickade. Skriptet utför sedan den operation som ska göras.
Problemet med denna metod är att vi ju har tre olika operationer
som ska utföras motsvarande de tre knapparna. För att veta vilken
operation som ska utföras ger man de tre knapparna samma namn men
olika värde i de olika formulären. php-scriptet kan, med hjälp av denna
variabels värde, avgöra vilket formulärs operation som ska utföras.
Observera att en 'submit'knapps värde är den text som visas på knappen.
För att detta ska fungera ska de olika 'submit'knapparna ha samma
name-egenskap.
Alternativt till att använda 'submit'knappens värde så kan man istället
använda en gömd (hidden) input-variabel med olika värde i de olika
formulären.
- Ange ett php-script som 'action' i form-elementet. Detta script
utför den operation som ska göras och avslutar med att med en
http-redirect omdirigera klienten tillbaka till den ursprungliga
adressen. Eftersom en http-header alltid kommer före en eventuell
meddelandekropp är det viktigt att operations-php-scriptet INTE
returnerar någon html-kod utan istället endast utför de operationer
som ska ske varpå man slutligen anropar
header("Location: sidan-man-vill-ska-visas.php");
Funktionen
header används just till att ändra http-headern (exempelvis
kan man returnera andra MIME-typer genom
header("Content-type: text/plain");
För att förtydliga ytterligare: Strukturen på skriptet som anropas från
formuläret ska vara:
<?php
kod som utför den önskade operationen men som INTE printar ut något
header("Location: sidan-man-vill-ska-visas.php");
?>
Normalt använder man en av dessa metoder, men för att öva så ska du använda
bägge metoderna. Skickandet av mail ska göras av ett separat skript, dvs med
metod 2 ovan. Insättande av nya personer, resp köksanvariga ska ske
enligt metod 1 ovan, dvs direkt från websidans php-script (med hjälp
av funktioner i en separat fil).
Arbetsgång
- Börja med att skapa tabellerna i databasen. Se
föreläsningsanteckningarna, kapitel 8 i boken samt informationen
från laboration 2. Var och en av er har fått en Postgresql-databas med
samma
namn som ert användarnamn. Om ni arbetar i en grupp om 2, använd den ena
databasen. Logga in på nestor och starta psql för att i databasen skapa
två tabeller 'Anvandare' och 'Koklista'.
Den ena tabellen innehåller de potentiella köksansvariga och bör
innehålla åtminstone kolumnerna, "namn" och "datorpost" där
"namn" är nyckel. Den andra tabellen innehåller kolumnerna
"veckonr" och "namn" där "veckonr" är nyckel. Den senare tabellen är
kopplad till den förra genom en ett-till-många-relation till
den förra tabellen det vill säga den förra tabellens nyckel är en
främmande nyckel i den senare.
- Gör nu filen "koklista.php" som skapar websidan. Det är denna fil som
ska anropas från webläsaren med adressen:
http://nestor.nada.kth.se/~DITT ANVÄNDARNAMN/koklista.php
vilket betyder att den måste ligga i din underkatalog public_html.
Enklaste sättet att skapa denna fil är att ladda ner denna
labbinstruktion och sedan editera bort allt som inte ska finnas i
filen. Observera att det som finns i labbinstruktionen är statiskt och
ni ska steg för steg införa dynamiska delar.
- Se till att nya användare stoppas in då man trycker på knappen
"Ny person" (se punkt 1 under kommentarer ovan).
PHP-koden i filen ska anropa en funktion setAnvandare($namn, $mailaddr)
som skrivs i en fil som kallas "kitchen.php". Denna fil ska innehålla
ett antal
funktioner som hanterar databasen. Endast funktioner i denna fil ska
känna till vad databasen och dess tabeller heter.
Funktionen setAnvandare utför en INSERT-sats för att stoppa in namn
och mailadr i tabellen 'Anvandare'. Se exempel i föreläsningarna. Testa
att det fungerar genom att använda psql för att se på databasen.
- Ändra nu funktionen setAnvandare så att den använder en SELECT-sats för
att kontrollera om namnet redan finns i tabellen.
Om namnet finns, utförs en UPDATE-sats, i annat
fall utförs en INSERT-sats. Se exempel i föreläsningarna.
Effekten av detta är att i tabellen 'Anvandare' blir namn en unik
nyckel dvs varje namn förekommer endast en gång. Testa
att det fungerar genom att använda psql för att se på databasen.
- Ändra formuläret som stoppar in veckonummer och namn i tabellen
'Koklista'. Detta formulär innehåller en meny av
användare. För denna behövs i "kitchen.php" en funktion getAnvandare()
som printar ut <option>-rader för html-select-meny med alla
"användare" som ligger i köksdatabasen, t.ex.
<option>Jan Banan</option>
<option>Kalle Kula</option>
<option>Kalle Svensson</option>
-
Det behövs i "kitchen.php" en funktion setKokansv($veckonr, $namn)
som fungerar analogt med setAnvandare ovan.
Här är det veckonumret som ska vara unikt.
- Lägg till kod som generarar en html-tabell
som innehåller veckor och namn från och med nuvarande vecka och
framåt, ordnad efter veckonummer, något i stil med:
Veckonr | Namn |
8 | Kalle Svensson |
9 | Jan Banan |
10 | Kalle Svennson |
html-koden för ovanstående tabell ser ut ungefär:
<table>
<tr><th>Veckonr</th><th>Namn</th></tr>
<tr><td>8</td><td>Kalle Svensson</td></tr>
<tr><td>9</td><td>Jan Banan</td></tr>
<tr><td>10</td><td>Kalle Svennson</td></tr>
</table>
tr står för "table row", td står för "table data".
Veckonumret för idag kan fås genom funktionen strftime("%V");
Html-tabellen genereras av funktionen getKokLista($veckonr) i "kitchen.php".
Denna funktion liknar getAnvandare men printar ut <tr>-rader istället.
- Lägg nu till formuläret med knappen för att skicka datorbrev till
dagens köksanvarig. I detta fall ska en fil "kokmail.php"
anropas (se punkt 2 under kommentarer ovan).
Koden i denna fil använder strftime och funktionen
getAnsvMail($veckonr) i "kitchen.php".
Om det finns någon köksanvarig returnerar getAnsvMail dennes mail-adress,
i annat fall returneras en tom sträng.
Om någon köksansvarig hittas ska ett email skickas till denne
där personen upplyses om att han/hon är köksansvarig.
Om ingen köksansvarig hittas skickas ett mail till testinge@nada.kth.se som
upplyser mig om att ingen anvarig finns.
OBSERVERA att Subject för er mail ska vara "Köksanvarig" så jag enkelt
kan sortera undan den drös av mail jag får.
Tips (läs igenom innan ni frågar)
För databastips, se föreläsningsanteckningarna om databaser,
webprogrammering, samt kapitel 8 i boken.
Det finns flera PHP-funktioner som hanterar Postgresql-databaser, men ni
klarar er med dom här fyra:
pg_connect,
pg_close,
pg_query och
pg_fetch_row.
För mer information om hur man gör formulär, se föreläsningsanteckningarna
samt kapitel 3.7 i boken.
En SQL-sats innehåller ofta citattecken. Om en PHP-variabel ska innehålla
citattecken använder man t.ex. dubbla citattecken för att markera början och
slut på strängen, och enkla citattecken inne i själva strängen. T.ex.
$sql = "SELECT foo FROM bar WHERE name='berra' AND email='berra@berra.com'";