Sessiot - Demo 6
Harjoitellaan sessioiden käyttöä WWW-sovelluksen tekemisessä. Toteutaan ensin yksinkertainen lomake, joka laskee lukuja yhteen. Toteutetaan sen jälkeen WWW-pohjainen ostoskori.
Laskuri

- Luo aluksi normaali XHTML-sivu PHP:lla. Tallenna sivu V-asemalle tai peopleen.
- Tallenna uusin versio formcontrol.php:sta samaan hakemistoon.
- Ota formcontrol.php käyttöön require-komennolla. Ohjeet luokat käyttöön löytyvät luennolta 10.
- Luo sivun alussa uusi tekstilaatikko, jonka otsikkona on Anna luku ja name-ominaisuudessa luku.
- Tee body-osaan lomake, jonka action-attribuutissa on $_SERVER['PHP_SELF']. Lisää lomakkeelle olion avulla luotu tekstilaatikko ja submit-painike.
- Tee uusi funktio, joka testaa onko tekstilaatikon arvoksi syötetty tieto numero (is_numeric). Aseta se tekstilaatikon tarkistusfunktioksi. Laita virheentulostus päälle. Määrää tekstilaatikko hakemaan arvonsa $_REQUEST-muuttujasta. Kokeile lomakkeen toimintaa.
- Summan tuloksen säilyttämiseksi tarvitaan sessiomuuttujaa. Lisää lomakkeen alkuun require-funktion jälkeen komento
session_start(). Määrää sessiomuuttujan alkuarvoksi 0.$_SESSION["summa"] = 0;
Tulosta sessiomuuttujan arvo body-osassa. - Tarkista onko sessiomuuttujaa summa asetettu (isset).
- Jos ei ole niin silloin voidaan laittaa alkuarvo nolla, kuten yllä.
- Jos on, niin tarkista onko tekstilaatikko validi (is_valid).
- Jos arvo oli numero, niin lisää se sessiomuuttujaan summa.
- Nyt edellinen syötetty numero tulee valmiiksi tekstilaatikkoon. Poista tämä asettamalla summausten jälkeen tekstilaatikon arvoksi tyhjän (set_value).
- Testauksessa kannattaa käyttää Web Developer Toolbarista löytyvää valintaa Cookies | Clear Session Cookies. Näin pääset laskurin alkutilaan.
Ostoskori
Toteutussuunnitelma ostoskorille:
- Toteutetaan tuotetaulukko, josta voi lisätä linkkiä klikkaamalla tuotteita koriin.
- Tehdään ostoskori-sivu, joka tallentaa lisätyt tuotteet sessiomuuttujiin ja osaa tulostaa ne.
- Laajennetaan ostoskoria siten, että voidaan poistaa tuotteita tai muuttaa niiden määriä.
Tuotetaulukko
Toteutaan ensin tuotetaulukko, josta voi lisätä tuotteita ostoskoriin.

- Luo uusi PHP-tiedosto tuoteluettelo.php, johon lisäät tuotevaihtoehdot taulukkona. Esim.
<?php $tuotteet = array("Omena", "Banaani", "Appelsiini", "Kiwi"); ?> - Tee toinen normaali PHP-sivu, johon liität require-komennolla tuotteet-taulukon.
- Lisää alkuun kutsu
session_start()-funktioon niin, että sessiomuuttujat saadaan käyttöön. Toistaiseksi tällä sivulla emme tarvitse sessiomuuttujia, mutta määritys on tarpeen sessiomuuttujien säilymisen kannalta. - Tee body-osaan foreach-silmukka, joka tulostaa taulukon kaikki vaihtoehdot XHTML-taulukkona. Kukin tuote tulee omalle rivilleen.
- Lisää silmukan sisällä olevaan tulostukseen toinen td-elementti, jonka sisään linkki ostoskoriin:
<a href=\"ostoskori.php?$tuote=1\">Lisää ostoskoriin</a>
Huom! People-palvelimella ei tarvitse välttämättä olla .php-päätettä ollenkaan. Tuotteen nimessä ei saa olla välilyöntejä, sillä nämä muuttuvat $_REQUEST-taulukossa alaviivoiksi ja aiheuttavat url-enkoodamattomana ongelmia linkeissä.
Ostoskori
- Tee uusi PHP-tiedosto ostoskori.php. Lisää alkuun require-komennolla tuoteluettelo.php.
- Lisää alkuun
session_start(), että sessiomuuttujat saadaan käyttöön. - Lisätään sessiomuuttujaan lisätyn tuotteen määrä. Käy läpi kaikki tuotteet foreach-silmukassa.
Tutki onko $_REQUEST-muuttujassa määritelty kierroksella määritelty tuote ja jos on, niin
- Tutki onko vastaavan nimistä sessiomuuttujaa asetettu
- Jos sessiomuuttuja on asetettu, niin lisää $_REQUEST-muuttujasta kyseisen tuotteen määrä samannimiseen sessiomuuttujaan.
- Jos sessiomuuttujaa ei ole vielä asetettu, niin alusta samanniminen
sessiomuuttuja $_REQUEST-muuttujasta saadulla arvolla. Esim.
$_SESSION[$tuote] = $_REQUEST[$tuote];
- Tutki onko vastaavan nimistä sessiomuuttujaa asetettu
- Lisää body-osan alkuun linkki tuotteet-sivulle.
- Tulostetaan XHTML-taulukko, jossa on lisätyt tuotteet ja niiden määrä. Käy body-osassa läpi kaikki tuotteet foreach-silmukalla. Tarkista onko kyseisen niminen sessiomuuttuja asetettu. Jos on, niin tulosta XHTML-taulukon rivi, jossa on ensimmäisessä solussa tuotteen nimi ja toisessa tuotteen määrä.
Ostoskorin muokkaaminen

- Lisää ihan ostoskori-skriptin alkuun require-komennolla käyttöösi formcontrol.php:n lomake-elementit. Määrityksen on tultava ennemmin session_start() -komentoa tai muuten olioita ei voidaan tallentaa sessioon.
- Muokkaa tietyn tuotteen sessiomuuttujan alustamista siten, että luot sessiomuuttujaan CText-tyyppisen olion, jonka oletusarvona on $_REQUEST:ista tullut luku. Tekstilaatikon nimenä ja otsikkona on tuotteen nimi. Esim.
$_SESSION[$tuote] = new CText($tuote,$_REQUEST[$tuote],$tuote, 3);
- Muokkaa arvon lisäystä siten, että ensin haet sessiomuuttujasta (= CText-tyyppinen olio) nykyisen arvon (get_value()).
Lisää tähän arvoon $_REQUEST-muuttujasta tullut luku. Aseta yhteenlaskettu arvo olion uudeksi arvoksi (
set_value()). - Lisää body-osaan lomake (form-elementti), joka viittaa ostoskoriin (
$_SERVER['PHP_SELF']) - Muokkaa body-osassa olevaa silmukkaa siten, että nyt tulostetaankin pelkästään olio (ja samalla sen label).
echo "<tr><td>",$_SESSION[$tuote],"</td></tr>";
- Lisää submit-painike ja aseta tämän name-ominaisuudeen arvo muuta.
- Kokeile toimiiko tuotteiden lisääminen tuote-sivujen kautta. Miksi CText-olion ei tarvitse kutsua set_from_request()-metodia saadakseen järkevän arvon? Kokeile mitä tapahtuu kun painat ostoskorissa muuta-painiketta. Miksi näin käy?
- Ongelmana on erottaa onko tarkoitus lisätä tuote vai muuttaa tuotteen määrä.
Lisää ennen sessiomuuttujan olemassaolon kyselyä if-lause, jossa tarkistat onko
$_REQUEST["muuta"]asetettu.- Jos on asetettu, niin aseta sessiomuuttujaan (olio) arvo suoraan lomakkeelta saaduista tiedoista (
set_from_request()). - Jos ei ole asetettu, niin sitten voidaan lisätä arvo tai luoda uusi sessiomuuttuja (edellinen if-else toisen
else-osan sisälle).
- Jos on asetettu, niin aseta sessiomuuttujaan (olio) arvo suoraan lomakkeelta saaduista tiedoista (
Ostoskorista poistaminen

- Lisää body-osaan ennen tuotteen tulostusta uuden CCheckboxin luonti. Anna name-ominaisuuteen poista ja valueen tuotteen nimi. Otsikkona voi olla teksti Poista.
- Aseta tekstilaatikon arvo $_REQUEST-muuttujasta (
set_from_request()) - Tarkista onko laatikko valittuna (
is_checked())- Jos on valittu, niin poista kyseinen sessiomuuttuja (unset).
- Muutoin voi tulostaa tuotteen (olio) ja checkbox-laatikon.
- Kokeile poistamista.
Ostoskori ilman evästeitä
Normaalissa tapauksessa sessiotunniste välitetään evästeiden avulla. Evästeitä ei välttämättä ole kuitenkaan käytössä kaikissa selaimissa, joten tunniste pitää välittää linkeissä tai lomakkeen piilokenttänä.
- Siirrä demo-sivusi peopleen elleivät ne ole jo siellä.
- Valitse Web Developer Toolbarista valinta Cookie | Clear Session Cookies.
Estä tämän jälkeen Mozilla Firefoxin asetuksista evästeiden käyttö valinnalla Tools | Options | Privacy | Cookies |
Exceptions. Kirjoita people.cc.jyu.fi ja napauta Block.

- Kokeile muutamaan kertaan lisätä samaa tuotetta koriin. Kokeile muuttaa tuotteen määrää.
- Lisätään sessiotunnisteen välitys lomakkeelle. Lisää demotehtävähakemisoon .htaccess-tiedosto ja lisää siihen rivit
php_value display_errors on php_value session.use_trans_sid 1 php_value url_rewriter.tags "a=href,area=href,frame=src,input=src,fieldset=fakeentry" php_value arg_separator.output &
- Lisää lomakkeeseen vielä fieldset lomake-elementtien ympärille ellet ole jo sellaista tehnyt. Sessiotunniste tulee automaattisesti tämän sisälle.
- Lisää vielä tuotteet.php:n linkkeihin sessiotunniste:
<a href=\"ostoskori.php?$tuote=1&".strip_tags(SID)."\">Lisää ostoskoriin</a>
Sessiotunniste ei tule automaattisesti dynaamisiin linkkeihin.
- Nyt lomakkeen pitäisi toimia ilman evästeitäkin. Mitä tietoturvaongelmia tällaisessa sessiotunnisteen välittämisessä kuitenkin on? Poista Firefoxin asetuksista evästeiden estäminen people.cc.jyu.fi:ssä.
Tuotteiden määrä selauksessa

- Lisää vielä tuotteet-sivulle montako kappaletta kutakin tuotetta on lisätty ostoskoriin.
Tarvitset formcontrol.php-luokan määrityksiä, lisää require-komento ennen
session_start()-funktiota. - Kokeile vielä muuttaa tuotteiden määrää tuoteluettelo.php:ta muokkaamalla.

