bild
Skolan för
elektroteknik
och datavetenskap

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

VeckonrNamn
25Inge Frick
33Jan Banan
35Kalle Kula

Veckonr:
Ansvarig:

Sätt in ny person

Namn:
Datorpost:

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:

  1. 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.
  2. 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

  1. 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.
  2. 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.
  3. 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.
  4. Ä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.
  5. Ä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>
    
  6. 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.
  7. 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:
    VeckonrNamn
    8Kalle Svensson
    9Jan Banan
    10Kalle 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.
  8. 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'";

Copyright © Sidansvarig: Stefan Nilsson <snilsson@nada.kth.se>
Uppdaterad 2007-04-19