Sessiot, evästeet ja tiedostot - Demo 5
Harjoitellaan sessioiden käyttöä WWW-sovelluksen tekemisessä. Toteutaan ensin sessioilla yksinkertainen lomake, joka laskee lukuja yhteen. Yritetään sen jälkeen toteuttaa vastaava lomake evästeiden avulla. Lisäksi toteutetaan lomake, jolla voi kirjoittaa rivin tekstitiedostoon tai tyhjentää tekstitiedoston. Lopuksi toteutetaan yksinkertainen lomake, jolla voi ladata tiedoston palvelimelle.
Laskuri sessioilla

- Luo aluksi normaali XHTML-sivu PHP:lla. Tallenna sivu W-asemalle.
- Tee body-osaan lomake, jonka action-attribuutissa on $_SERVER['PHP_SELF']. Lisää lomakkeelle tekstilaatikko, jonka otsikkona (label) on "Anna luku" ja name-ominaisuudessa luku. Lisää lomakkeelle lisäksi submit-painike.
- Määrää tekstilaatikko hakemaan arvonsa (value) $_REQUEST-muuttujasta. Kokeile lomakkeen toimintaa.
- Summan tuloksen säilyttämiseksi tarvitaan sessiomuuttujaa. Lisää lomakkeen alkuun komento
session_start();. - Tarkasta ennen lomakkeen tulostamista, onko lukua $_REQUEST-muuttujassa
(isset()).
Jos luku löytyy, niin tarkista onko se numero (is_numeric()).
Jos luku on numero, niin tarkasta löytyykö sessiomuuttujaa summa. Jos muuttuja löytyy, niin lisää muuttujan
arvoon $_REQUEST-muuttujassa oleva arvo. Jos sessiomuuttujaa ei ole, niin luo sellainen ja laita arvoksi
$_REQUEST-muuttujassa oleva arvo.
if(isset($_SESSION['summa'])) { $_SESSION['summa'] += $_REQUEST['luku']; } else { $_SESSION['summa'] = $_REQUEST['luku']; } - Jos sessiomuuttuja summa on asetettu, niin tulosta sen arvo body-osassa.
- Testauksessa kannattaa käyttää Web Developer Toolbarista löytyvää valintaa Cookies | Clear Session Cookies. Näin pääset laskurin alkutilaan.

Laskuri evästeillä
Edellisen esimerkin laskurin voisi periaatteessa tehdä evästeillä. Tällöin summaa olisi mahdollista tallentaa myös selaimen sulkemisen ajaksi. Muuta edellisen esimerkin laskuri toimimaan evästeillä sessioiden sijaan.
- Evästeen asettaminen:
setcookie('summa', $_REQUEST['luku'], time()+24*60*60);- Eväste on asetettava ennen varsinaista dokumenttia, koska se tulee HTTP-otsikkotietoihin.
- Evästeen kestoksi tulee siis yksi päivä.
- Evästeeseen viittaaminen:
if(isset($_COOKIE['summa']))... - Testaa laskurin toimintaa. Kokeile myös sulkea välillä selain ja palata sitten samalle sivulle.
- Toiminnasta huomaa sen virheen, että summa päivittyy oikeaksi aina vasta seuraavalla sivun latauksella. Tämä johtuu siitä, että evästeen arvo on käytettävissä aina vasta seuraavalla sivun latauskerralla. Sessioissa taas arvoa voidaan käyttää heti sen asettamisen jälkeen.
- Evästeet voi poistaa Web Developer Toolbarin toiminnolla Cookies | Delete Path Cookies.
- Korjaa toiminta siten, että tuloksena näytetään evästeen arvon ja lomakkeelta lähetetyn arvon summa.
- Voit hyödyntää myös dokumentin alussa tehtyjä jossitteluja. Sijoita näytettävä arvo esimerkiksi $summa-muuttujaan.
Toinen vaihtoehto olisi tehdä jokin välisivu ennen summan näyttämistä. Näin saisimme väliin evästeiden vaatiman yhden ylimääräisen sivun latauksen.

Tiedostojen käsittely

Tehdään lomake, jolla voi kirjoittaa rivin tiedostoon tai tyhjentää tiedoston.
- Aloita uusi XHTML-sivu PHP:lla. Tallenna sivu W-asemalle.
- Luo sivulle mallikuvan näköinen lomake. Lomakkeella on siis tarkoitus valita valintanapin (radio) avulla lisätäänkö tiedostoon tekstiä vai tyhjennetäänkö tiedosto. Lisäksi lomakkeella on tekstikenttä tekstiä varten ja submit-painike.
- Laita lomakkeen käsittelijäksi $_SERVER['PHP_SELF'].
- Tutki tiedoston alussa, onko submit-painiketta painettu. Jos painiketta on painettu,
kirjoitetaan tiedostoon lisää tekstiä tai tyhjennetään tiedosto:
- Tutki valintanapin arvosta, halusiko käyttäjä tyhjentää tiedoston vai lisätä sinne rivin.
- Jos käyttäjä halusi tyhjentää tiedoston, avaa tiedosto (esimerkiksi "testi.txt")
kirjoitustilaan siten, että kirjoitus alkaa tiedoston alusta ja vanha sisältö tuhotaan. Kirjoita sen
jälkeen tiedostoon tyhjä merkkijono.
$tiedosto = fopen("testi.txt", "w"); fwrite($tiedosto, ""); - Jos käyttäjä taas halusi lisätä rivin tiedoston, avaa tiedosto (esimerkiksi "testi.txt") kirjoitustilaan siten, että kirjoitus alkaa tiedoston lopusta ja vanha sisältö säilytetään. Kirjoita sen jälkeen tiedostoon käyttäjän tekstikentässä syöttämä arvo (tutki ensin oliko arvo joku muu kuin tyhjä, jottet kirjoita turhaan). Koodaa käyttäjän mahdollisesti syöttämät tagit ennen kirjoitusta (htmlentities()). Kirjoita rivin perään myös rivinvaihto.
- Muista lopuksi sulkea tiedosto.
- Muista asettaa tiedostoille ja kansioille riittävät kirjoitusoikeudet.
- Tulostetaan vielä sivun loppuun tiedoston rivit pre-elementin sisälle:
- Tutki ensin onko tiedostoa olemassa (file_exists()).
- Jos tiedosto löytyy, niin lue sen kaikki rivit johonkin taulukkomuuttujaan.
- Tulosta sen jälkeen kaikki rivit pre-elementin sisälle.
- Testaa lomakkeen toimintaa. Kokeile kirjoittaa myös XHTML-koodia, niin näet toimiiko merkkien koodaus.
Tiedoston lataus palvelimelle

Tehdään yksinkertainen lomake, jolla voi ladata tiedoston palvelimelle.
- Aloita uusi XHTML-sivu PHP:lla. Tallenna sivu W-asemalle.
- Tee samaan hakemistoon myös kansio tiedostot ja laita sille kirjoitusoikeudet päälle kaikille.
- Tee sivulle lomake, jolla voi ladata tiedoston palvelimelle:
- Muista laittaa form-elementille määritys enctype="multipart/form-data.
- Laita lomakkeelle piilokenttä (hidden), jossa määräät tiedoston maksimikooksi 100 kt. Piilokenttä täytyy olla sivulla ennen tiedostokenttää. Huomaa, että tämä ei ole vedenpitävä rajoitus! (miksi?)
- Laita lomakkeen käsittelijäksi $_SERVER['PHP_SELF'].
- Tutki tiedoston alussa, onko submit-painiketta painettu. Jos painiketta on painettu,
lisätään palvelimelle tiedosto:
- Testaa ensin, onko käyttäjä valinnut tiedoston. Voit testata esimerkiksi onko tiedoston koko yli 0 tavua.
if($_FILES['tiedosto']['size']>0) {... - Jos käyttäjä oli valinnut tiedoston, testaa seuraavaksi onnistuisiko tiedostonsiirto,
mutta älä vielä siirrä itse tiedostoa.
if(is_uploaded_file($_FILES['tiedosto']['tmp_name'])) {... - Jos tiedostonsiirto vaikuttaisi onnistuvan, siirrä tiedosto kansioon tiedostot.
Muista viedä parametrina koko tiedostopolku (myös tiedoston nimi), pelkkä kansion nimi ei riitä.
move_uploaded_file($_FILES['tiedosto']['tmp_name'], $tiedostopolku);
- Testaa ensin, onko käyttäjä valinnut tiedoston. Voit testata esimerkiksi onko tiedoston koko yli 0 tavua.
- Tulosta käyttäjälle lomakkeen alkuun tieto tiedonsiirron onnistumisesta tai epäonnistumisesta (mallikuva). Käytä hyväksesi $_FILES['tiedosto']['error']-taulukkoa.
- Testaa lomakkeen toimintaa. Kokeile ladata myös yli 100 kt oleva tiedosto, niin näet toimiiko kokorajoitus.
- Jos aikaa jää, voit parantaa lomaketta siten, että latauksen epäonnistuessa lomakkeelle tulostetaan syy siitä, miksi lataus epäonnistui. Apuna voi jälleen käyttää $_FILES['tiedosto']['error']-taulukkoa.
- Lisäksi olisi järkevää tarkistaa ainakin tiedostopääte, jottei palvelimelle voi ladata vaikkapa vahinkoa tekeviä skriptejä. Sen tarkistaminen jätetään kuitenkin viikkotehtäväksi. Pohdittavaksi jää myös minne saatu data kannattaa tallentaa ja millaisilla oikeuksilla tiedostoihin (tai tietokantatietueisiin) pääsee käsiksi.
Lisätehtävä
Laajenna tiedoston käsittelytehtävää siten, että aluksi kysytään käyttäjältä minkä nimistä tiedostoa käsitellään. Sen jälkeen haetaan kyseisen tiedoston sisältö lomakkeelle textarea-kenttään. Käyttäjä voi sitten tehdä tiedostoon muokkauksia ja muokkaukset tallennetaan samaan tiedostoon käyttäjän painettua submit-painiketta. Tällä periaatteella voisi siis esimerkiksi tehdä alkeellisen nettisivujen päivitystoiminnon ilman, että sivuja tarvitsisi siirrellä FTP:llä tai SSH:lla. Palveluun olisi luonnollisesti järkevää päästä vain kirjautumisen kautta väärinkäytösten estämiseksi.


Käyttäjien kommentit