PHP ja WWW-lomakkeet
Tehdään kurssille arvosanalaskuri opiskelijan ja opettajan tueksi.
Lomake PHP:lla

- Luo W-aseman sovellukset-hakemistoon uusi alihakemisto demo3 ja luo sinne uusi PHP-tiedosto index.php
- Avaa lomakkeen pohja ja kopioi kaikki XHTML-elementit PHP-sivulle.
- Korjaa alun XML-deklaraatio siten, että se tulostetaan
printtaiecho-komennolla. Muutoin sivu ei toimi. Muista<?php ?>-tagit aina koodia kirjoitettaessa. - Kokeile sivua osoitteesta http://users.jyu.fi/~omatunnus/sovellukset/demo3/.
- Aseta lomakkeen käsittelijäksi sivu itse. Tämä onnistuu helpoimmin esimääritellyllä $_SERVER['PHP_SELF'] -muuttujalla.
Tietojen validointi
- Tee lomakkeen alkuun tarkistus, että etunimi ja sukunimi on täytetty ja tiedekunta on valittu.
- Tee tarkistukset ehtorakenteiden avulla.
- Tarkistuksissa tarvitset $_REQUEST-muuttujaa, empty-funktiota ja/tai vertailuoperaattoreita.
- Lisää virheilmoitukset yhteen virhetaulukkoon, jossa avaimena käytetään virheellisen kentän nimeä ja arvona virheilmoitustekstiä (kts. luentoesimerkin virheentarkistukset).
- Jos tiedot ovat ok, niin tulosta toistaiseksi etunimi, sukunimi ja tiedekunnan numero.
Tulosteista kannattaa poistaa HTML-erikoismerkit htmlentities-funktiolla.
- Joudut jakamaan dokumentin kahteen osaan ehtorakenteella: toisessa osassa on kaikki lomakkeen tulostamiseen liittyvät jutut ja toisessa osassa varsinaiset tulokset.
- Tulokset näytetään, jos submit-nappulaa on painettu eikä virheitä ole tullut.
- Jos tiedoissa oli virheitä, niin tulosta virhe-ilmoitus
- Ensimmäinen versio: Jos virheitä on niin tulosta yleinen virheilmoitus ja estä lomakkeen näyttö. Tarvitset isset-funktiota.
- Toinen versio: Käy läpi kaikki virhetaulukon virheet ja tulosta ne lomakkeen alussa (ns. Korppi-metodi :D ).
- Kolmas versio: Tulosta lomake-elementin viereen virheilmoitus.
- Neljäs versio: Mieti mikä tässä tavassa on koodin ylläpidon kanssa ongelmallista? (ei tarvitse toteuttaa mitään vielä)
- Tekstikentissä, joihin pitäisi syöttää viikkotehtävien pisteet, ei ole vielä
name-ominaisuutta asetettu. Mitäname-ominaisuuksiin pitäisi laittaa, että saat kaikki viikkotehtäväpisteet suoraan taulukkona? Kokeile selvittää, mitä tietoja lomakkeelta tulee print_r-funktiolla. Näin voit testata tulivatko viikkotehtäväpisteet taulukkona. - Tarkista, että viikkotehtäviin on laitettu numero. Tarkista, että numero on väliltä 0-5.
Älä kuitenkaan herjaa tyhjästä tekstilaatikosta. Kokeile
tehdä tarkistus siten, että käyt yhdessä silmukassa läpi kaikki viikkotehtävien syötteet.
Koko ryhmää koskeva virheilmoitus riittää toistaiseksi.
- Voit tarvita funktioita is_numeric, in_array sekä silmukka- ja ehtorakenteita.
- Kokeile lomakkeen lähetysmetodiksi post. Muuttuiko lomakkeen toiminta? Napauta selaimen osoiteriville ja paina enteriä, jos haluat testata lomaketta, niin ettei POST-muuttujia lähetetä uudelleen.
Laskentaa
Tulostetaan keskiarvo, jos kaikki tiedot on hyväksytty. Lasketaan aluksi normaali keskiarvo, jonka voi myöhemmin muuttaa painotetuksi keskiarvoksi.
- Summaa viikkotehtäväpisteet foreach-silmukalla johonkin väliaikaiseen muuttujaan.
- Laske syötettyjen kertojen määrä taulukosta count-funktiolla.
- Huomaa, että
koska kyse on tekstilaatikoista, niin jokaisesta laatikosta tulee vähintään tyhjä merkkijono.
count-funktion arvoksi siis pitäisi tulla aina 9. Sama ei päde esim.
selecttaicheckbox-käyttöliittymäkomponentteihin. Aiheesta tarkemmin W3C:n forms-dokumentissa. Koska tekstilaatikoiden määrä on kiinteä, niin turvallisinta olisi selvittää tekstilaatikoiden määrä jostain muualta kuin käyttäjän syötteestä.
- Huomaa, että
koska kyse on tekstilaatikoista, niin jokaisesta laatikosta tulee vähintään tyhjä merkkijono.
count-funktion arvoksi siis pitäisi tulla aina 9. Sama ei päde esim.
- Jaa pistesumma kertojen määrällä ja printtaa se tulossivulle sopivan XHTML-elementin sisälle.
Oletusarvojen täyttö
- Virhe-ilmoituksien yhteydessä on hyvä laittaa lomakekenttiin ne arvot mitä käyttäjä ensimmäisellä kerralla antoi, ettei tietoja tarvitse kirjoittaa uudestaan. Tulosta nämä tiedot tekstikenttien value-ominaisuuteen.
- Käyttäjä voi syöttää myös jotain HTML-koodia. Muunna HTML:n erikoismerkit entiteeteiksi htmlentities-funktiolla
- Oletusarvoa kannattaa tulostaa
value-ominaisuuteen vain, kun lomake on lähetetty ja virheitä on ilmaantunut. Tee siis tarkistus onko virhetaulukkoa olemassa ennen kuin tulostat oletusarvoksi mitään.
Dynaaminen valintalista
Ongelmana on saada selected="selected" oikean
option-elementin kohdalle.
Koodi pystyy paremmin ylläpidettävänä, kun emme jokaisen
option-elementin kohdalla jossittele
oliko tämä edellisellä täyttökerralla valittu vaihtoehto.
- Tee ensin taulukkomuuttuja, jossa on
option-elementin vaihtoehdot eli tiedekunnat. - Luo
select-elementin aloituksen ja lopetuksen väliinfor-silmukka, joka käy läpi taulukon alkiot. Aloita indeksinumero 0:sta ja päätä taulukon alkoiden määrään (count). - Tulosta
option-elementti, jossa on taulukon teksti javalue-ominaisuuteen indeksin arvo. - Kun indeksi on sama lomakkeelta saatu arvo, niin tulosta
option-elementtiin lisäksi teksti selected="selected". - Muuta onnistuneen lomakkeen täytön jälkeistä tulossivua siten, että tulostat tiedekunnan numeron sijaan tiedekunnan nimen. Tämä onnistuu tiedekuntataulukon avulla.
Soveltavia tehtäviä
Seuraavista tehtävistä saa hyvää treenausta vaativimpia viikkotehtäviä varten.
Dynaaminen taulukko
Mitä jos viikkotehtävien määrä muuttuu? Kuinka paljon muutosvaivaa on nähtävä?
- Lisää sivun alkuun muuttuja, joka kertoo viikkotehtävien määrän.
- Tee ensimmäisen
tr-elementin sisällefor-silmukka, joka käy läpi numerot yhdestä viikkotehtävien määrään. Tulostathjalabel-elementtejä silmukan sisällä. Numerot saat silmukan indeksistä. - Tee toisen
tr-elementin sisälle vastaava silmukka. Nyt on tulostettavatdjainput-elementtejä. - Keskiarvon laskennan pitäisi toimia edelleen, koska se käy kaikki tehtäväkerrat läpi.
Opettajan lomake
Miten opettaja voisi syöttää nopeasti monen opiskelijan tiedot ja saada kerralla kaikkien keskiarvot?

- Tallenna sivu toisella nimellä. Poista alusta henkilötietojen kyselyt.
- Lisää taulukkomuuttuja, jossa on muutaman oppilaan nimi.
- Kapseloi viikkotehtäväpisterivin tulostava silmukka toisella
foreach-silmukalla, joka käy läpi kaikki opiskelijat. - Tulosta rivin ensimmäiseen soluun (th) opiskelijan nimi.
- Tee
name-ominaisuudesta kaksiulotteinen taulukko, jossa ensimmäinen avain on opiskelijan nimi ja toinen avain on tehtävän numero. HTML-koodiin pitäisi tulla siis esimerkiksi<tr> <th scope="row">Nano Nano</th> <td><input type="text" name="vt[Nano Nano][1]" /></td> ... <td><input type="text" name="vt[Nano Nano][9]" /></td> </tr> <tr> <th scope="row">Diiba Daaba</th> <td><input type="text" name="vt[Diiba Daaba][1]" /></td> ... <td><input type="text" name="vt[Diiba Daaba][9]" /></td> </tr> ...- Lisätietoa: Huomaa, että HTML 4.0 ei salli name-attribuutin arvossa mitään erikoismerkkejä (esim. hakasulkeita, välilyöntejä tai ääkkösiä), mikä on PHP:n kannalta ongelmallista. XHTML on onneksi tässä suhteessa sallivampi. Jos haluat, että sivu on HTML4-yhteensopiva, joudutaan nimeäminen tekemään esimerkiksi tyyliin vt_n_m, missä n on opiskelijan nimen paikka taulukossa ja m on tehtävän numero. Tällaisten paramatrien läpikäynti ei tosin ole aivan niin sievää kuin valmiiksi $_REQUEST-muuttujasta saatavan taulukon. Tarkemmin aiheesta:
- Lisää keskiarvon laskennan ympärille
foreach-silmukka, joka käy kaikki opiskelijat. Tulosta ensin opiskelijan nimi. Käy sitten sisemmässä silmukassa opiskelijan tulokset läpi ja summaa ne. Tämä onnistuu, kun läpikäytäväksi taulukoksi antaa $_REQUEST['vt'][$opiskelijan_nimi]. Tulosta ulomman silmukan lopussa opiskelijan tehtävien keskiarvo.
Huomaa, että yhdellä labelilla ei pysty enää viittaamaan yhteen lomake-elementtiin. Tämä rikkoo hieman
lomakkeemme esteettömyyttä. Käyttämällä
th-elementeissä scope-ominaisuutta voidaan kuitenkin kertoa mikä on minkäkin taulukon solun otsikko.
Painotettu keskiarvo
Kurssilla arvioinnissa käytetään painotettua keskiarvoa. Muuta sovellusta siten, että se laskee normaalin keskiarvon sijaan painotetun keskiarvon seuraavan taulukon mukaan ($n = tehtävien määrä):
| Viikkotehtävä | Painokerroin |
|---|---|
| 1 - 2 | 1 |
| 3 - 4 | 1,5 |
| 5 - 7 | 2 |
| 8 - $n | 2,5 |
- Muuta foreach-silmukkaa siten, että saat taulukon avaimen johonkin muuttujaan.
- Lisää silmukkaan kertoimen määritys avaimen perusteella. Laske kertoimien summa. Painotettua keskiarvoa laskettaessa sitä tarvitaan jakajana. Jakaja (=kertoimien summa) tulee laskettua turhaan useampaan kertaan, mutta tämä ei nyt haittaa.
Lisätehtävää
Demopistelaskuri
Useiden matematiikan, fysiikan ja tietotekniikan kurssien arvioinnissa mitataan myös demotyöskentelyn aktiivisuutta. Aktiivisella demotyöskentelyllä saa lisäpisteitä tenttiin. Mieti miten laajentaisit opiskelijan arvosanalaskuria yleiseksi demopistelaskuriksi. Huomioitavaa:
- Kurssit ja näiden lisääminen
- Kurssien vaihteleva demokertojen määrä
- Bonuspisterajat
Jatkossa voisi miettiä myös seuraavia laajennusmahdollisuuksia:
- Useiden kurssitietojen muuttaminen kerralla
- Tietojen tallentaminen
- Kurssiarvosanalaskuri, jossa huomioidaan demobonus- ja tenttipisteet sekä arvosanan laskentatapa


Käyttäjien kommentit