Evästeet, sessiot ja tiedostot - Luento 9
- Luentotaltiointi
- Evästeet
- Sessiot
- Tiedostojen lataus palvelimelle
- Tiedostojen käsittely
- Edelleenohjaus
- Lisätietoa
Luentotaltiointi
- sovellukset09.mp3 17M
- sovellukset09.wmv 65M
- sovellukset09.avi 198M
Luennolla käsitellään evästeitä ja sessioita PHP:ssä. Esitellään niiden käyttötarkoituksia ja toimintaperiaatteita sekä syntaksia. Lisäksi käydään läpi tiedostojen käsittelyä (lukeminen, tallentaminen jne.) ja tiedostojen latausta palvelimelle lomakkeen avulla. Jos asia jää kesken, niin jatketaan sitä seuraavilla luennoilla.
Tämän luennon lähteenä on käytetty osittain Sami Kollanuksen tekemää PHP-opasta. Kiitokset!
Evästeet
Yleistä evästeistä
Evästeet ovat tekstimuotoista tietoa, jota palvelin voi lähettää selaimelle. Evästeelle voidaan määrätä haluttu elinikä, jonka ajan selain säilyttää evästeeseen talletettua tietoa. Oletuselinikä evästeillä on meneillään oleva sessio, joka tarkoittaa, että tietoa talletetaan vain siihen asti, kun selain suljetaan. Tyypillisesti selain säilyttää tällaisia session mittaisia evästeitä muistissa. Jos evästeen elinikä on määritelty pidemmäksi, tallentaa selain sen tiedostoon.
Seuraavan kerran, kun selain pyytää sivua, se lähettää evästeen palvelimelle. Palvelimella toimiva WWW-sovellus voi hyödyntää edellisellä kerralla talletettua tietoa. Evästettä voidaan ajatella siis eräänlaisena muuttujana, johon voidaan tallentaa tekstiä. Tieto on siten aina käytettävissä seuraavilla kerroilla, kun sivustoa käytetään.
Evästeessä voidaan säilyttää esimerkiksi ostoskorin tiedot verkkokaupassa, jolloin käyttäjä voi jättää ostoksensa kesken ja jatkaa niitä sujuvasti seuraavalla kerralla. Mitään arkaluontoista tietoa evästeissä ei kuitenkaan saa säilyttää, sillä ne ovat puhdasta kenen tahansa luettavissa olevaa tekstitietoa. Myöskään mitään tärkeää säilytettävää tietoa ei kannata tallettaa evästeissä, sillä ne ovat helposti poistettavissa.
Selaimella on aina jokin raja siitä, kuinka suuria evästeet saavat olla ja kuinka paljon niitä voidaan tallettaa. Jokaisen selaimen pitäisi kuitenkin minimissään täyttää suosituksen minimirajat:
- Evästeen maksimikoko vähintään 4 kt.
- Evästeitä voidaan tallentaa yhteensä vähintään 300.
- Voidaan tallentaa vähintään 20 evästettä palvelinta tai domainia kohti.
Evästeen asettaminen yleisesti
Palvelin lähettää evästeen http-vastauksen otsikkotiedoissa. Otsikkotiedoissa lähetetään selaimelle rivi, joka on seuraavaa muotoa:
Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure
NAME tarkoittaa evästeen nimeä ja VALUE arvoa (merkkijono), joka evästeelle annetaan. Nimi on ainoa pakollinen tieto, joka evästeelle täytyy joka tapauksessa määrittää. Muut tiedot voidaan haluttaessa jättää tyhjiksi.
expires-määritys määrittää ajan, mihin asti eväste on voimassa, eli mihin asti selainta pyydetään sitä säilyttämään. Aika (DATE) ilmoitetaan muodossa: "05-May-2004 07:31:27 GMT". Jos aikaa ei määritellä, on eväste oletuksena voimassa vain session ajan.
path-määritys määrittelee palvelimen polun, jossa eväste on voimassa. Oletuksena eväste on voimassa samassa kansiossa ja sen kansion alikansioissa. Tämä tarkoittaa sitä, että jokaisella kerralla, kun selain pyytää jotain sivua evästeen voimassaoloalueelta, se lähettää evästeen palvelimelle http-pyynnön mukana. Jos poluksi määritellään vain "/", on se voimassa koko domainissa.
domain-määrityksellä voidaan määritellä evästeen vaikutusalueeksi kaikki palvelimen alidomainit. Jos arvoksi määritellään esim. ".jyu.fi", on eväste voimassa kaikissa Jyväskylän yliopiston alidomaineissa.
secure-määrityksellä voidaan määrätä, että selain lähettää evästeen palvelimelle ainoastaan silloin, kun on käytössä salattu yhteys (HTTPS/SSL). Tämä ilmaistaan siis lisäämällä sana "secure" evästeen määreisiin.
Evästeen asettaminen ja poistaminen PHP:ssä
PHP-koodissa evästeen asettaminen toteutetaan setcookie()-funktiolla. Funktiosta on muistettava, että sitä täytyy kutsua ennen XHTML-koodin alkamista PHP-sivulla. Siis käytännössä kutsu täytyy olla ennen XML-versiomäärityksen tulostamista, joka on aina oltava XHTML-dokumentin ensimmäinen rivi. Alla on esimerkki setcookie()-funktion kutsusta.
setcookie("nimi", "tekstiä arvoksi", time()+60*60*24*30, "/", ".it.jyu.fi", 1);
Esimerkissä on käytetty kaikkia setcookie()-funktion parametreja. Kuitenkin ainoastaan ensimmäinen parametri eli evästeen nimi on pakollinen. Toisena parametrina voidaan antaa evästeen arvo merkkijonona.
Kolmas parametri on evästeen voimassaoloaika, joka annetaan "Unix timestamp" -muodossa. "Unix timestamp" on sekunteina ilmoitettuna aika, joka on kulunut vuoden 1970 alusta. PHP:ssä on esimerkissä käytetty time()-funktio, joka palauttaa tämän hetkisen ajan tuossa muodossa. Esimerkissä on lisätty siihen 30 päivää vastaava määrä sekunteja, jolloin eväste vanhenee 30 päivän kuluttua. PHP muuntaa tuon ajan automaattisesti evästeen vaatimaan muotoon.
Neljäs mahdollinen parametri setcookie()-funktiolle on evästeen yleisen asetttamisen yhteydessä käsitelty "path"-asetus. Viides parametri on samassa yhteydessä käsitelty "domain"-asetus. Kuudes ja viimeinen parametri on "secure"-asetus. Sen arvoksi voidaan antaa joko 0 tai 1. Esimerkissä on asetettu sen arvoksi 1, mikä tarkoittaa sitä, että selain lähettää evästeen ainoastaan salatun yhteyden yli.
Evästeen poistaminen tapahtuu samalla setcookie()-funktiolla, mutta arvon tulee olla tyhjä merkkijono. Poistaessa lisäksi voimassaoloaika on asetettava menneisyyteen, jotta poistaminen onnistuu oikein kaikilla selaimilla. Seuraava esimerkki selventää evästeen poistamista.
setcookie("nimi", "", time()-60*60*24*30);
Evästeen käyttö PHP:ssä
Evästeeseen viitataan PHP:ssä $_COOKIE-muuttujan avulla. Se on taulukkomuotoinen muuttuja, joka muodostuu automaattisesti selaimen lähettämistä evästeistä. Taulukon soluihin viitataan evästeen nimen perusteella. Alla on tästä esimerkki:
if(isset($_COOKIE['nimi'])) {
echo "Löytyi eväste 'nimi': ".$_COOKIE['nimi'];
}
Esimerkki evästeiden käytöstä
Asetetaan ensin eväste (esimerkiksi aseta.php):
<?php
// luo evästeen "nimi", jonka arvo on Antti
setcookie("nimi", "Antti");
// eväste "pyora" on voimassa seuraavat 5 minuuttia
setcookie("pyora", "Cannondale", time()+60*5);
?>
Käytetään evästettä (esimerkiksi index.php):
<?php
// haetaan luodut evästeet muuttujiin
$nimi = $_COOKIE["nimi"];
$pyora = $_COOKIE["pyora"];
// tulostetaan evästeiden tiedot
echo 'Henkilön '.$nimi.' pyörän merkki on '.$pyora.'.'."\n";
?>
Jos odotetaan viisi minuuttia, pyörän merkki ei enää näy sivulla (ladattaessa sivu uudelleen). Jos selain suljetaan ja avataan uudestaan, nimi häviää. Jos evästeet tuhotaan aiemmin esimerkiksi jonkun toisen PHP-sivun koodissa, kummatkin tiedot katoavat (ladattaessa sivu uudelleen).
Sessiot
Yleistä sessioista
Sessionhallinta on tekniikka, jonka avulla on tarkoitus säilyttää turvallisesti tietoa yhden session ajan, eli siihen asti, kunnes käyttäjä lopettaa session tai sulkee selaimen. Sessioilla toteutetaan usein esimerkiksi kirjautuminen erilaisiin palveluihin. Keskeisin ero evästeisiin on se, että sessiotietoa ei välitetä lainkaan selaimelle, vaan se säilytetään palvelimella. Palvelin säilyttää asetuksista riippuen sessiotiedon joko tiedostossa tai muistissa.
Silloin, kun sessio käynnistetään, sille luodaan yksilöllinen sessiotunniste. Sessioon voidaan sen jälkeen asettaa haluttu määrä ns. sessiomuuttujia. Sessiotietoon päästään möyhemmin käsiksi sessiotunnisteiden avulla. Tämän vuoksi sessiotunniste on jollain tavalla aina välitettävä selaimelle.
Sessiotunnisteen välittämiseen on PHP:ssä kaksi tapaa: välittää sitä URL:n mukana tai säilyttää evästeessä. PHP tekee tämän välittämisen automaattisesti, joten koodissa sitä ei tarvitse ottaa huomioon. Sen sijaan PHP:n asetuksia määritellessä tämä kannattaa ottaa huomioon. Sessiotunnisteen välittämiseen URL:n mukana sisältyy sellainen tietoturvariski, että sen tallentamista evästeeseen kannattaa yleensä suosia. Lisätietoa näistä sessioihin vaikuttavista PHP:n asetuksista saat PHP.net-sivustolta.
Sessiotunnisteen saa tarvittaessa selville session_id()-funktiolla.
Sessiot ilman evästeitä
Jos evästeitä ei ole käytettävissä, täytyy session tunnistetta kuljettaa mukana sivun osoitteessa parametrina tai lomakkeelle piilotettuna muuttujana.
Sessiotunnisteen kuljettaminen URL:n mukana lisää tietoturvaongelmia, koska tunniste voi kulkeutua sivun osoitteen mukana vääriin käsiin. Normaalisti sessio kannattaa siis säilyttää evästeessä!
Sessiot saa toimimaan ilman evästeitä asettamalla .htaccess-tiedostoon seuraavaa:
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 &
Nämä saavat PHP:n lisäämään sessiotunnisteen lomakkeille ja linkkeihin. Itse luotuihin dynaamisiin linkkeihin PHP ei aina osaa lisätä sessiotunnistetta, joten joskus pitää sessiotunniste lisätä seuraavasti:
echo '<a href="'.$dynosoite.'?param=2&'.strip_tags(SID).'">linkki</a>';
strip_tags(SID) ei palauta mitään, jos sessiot toimivat evästeillä. strip_tags()-funktiokutsu täytyy pitää mukana tietoturvasyistä.
Sessiomuuttujien käyttö
Sessiotietoon viitataan PHP:ssä $_SESSION-muuttujan avulla. Siihen viitataan ns. sessiomuuttujan nimen avulla. Uuden sessiomuuttujan asettaminen tapahtuu esimerkiksi seuraavasti:
$_SESSION['nimi'] = "jotain";
Sessiomuuttujaan voidaan viitata heti sen asettamisen jälkeen. Tämä on ero evästeisiin, jotka ovat käytettävissä vasta seuraavalla kerralla, kun sivu ladataan. Sessiomuuttujista on kuitenkin huomattava, että ennen niiden käyttöä on kutsuttava jokaisella sivulla session_start()-funktiota (ks. seuraava kappale).
Session käynnistäminen
Aina sessioita käytettäessä PHP:ssä täytyy jokaisella sivulla kutsua ensin session_start()-funktiota. Se tutkii ensin löytääkö se jo käynnissä olevan session tunnisteen evästeestä, URL:sta tai vastaanotetuista lomaketiedoista. Jos se löytää käynnissä olevan session, alustaa se automaattisesti $_SESSION-taulukkoon käytössä olevat sessiomuuttujat.
Session sulkeminen
Tallennettaessa sessioihin olioita täytyy aina muistaa kutsua session_write_close()-funktiota siinä vaiheessa, kun kaikki sessioihin liittyvät operaatiot on tehty sivulla. Funktio kirjoittaa tällöin sessiot valmiiksi ja lopettaa sessiot. Jos funktiota ei kutsuta, voi käydä niin, että olio ehtii "kuolla" ennen sessioiden kirjoittamista, jolloin olion arvoja ei saada talteen sessiomuuttujaan. Oliohan "kuolee" aina sivun suorituksen lopussa ja samalla hetkellä kirjoitetaan myös sessiot. Emme kuitenkaan voi olla varmoja kumpi tapahtuu ensin, minkä takia funktion kutsuminen on tarpeellista.
Jos sessioihin ei tallenneta olioita, session_write_close()-funktion käyttäminen ei ole välttämätöntä.
Session tuhoaminen
Sessio on tietoturvasyistä aina muistettava tuhota, jos vain mahdollista. Muussa tapauksessa sessiotieto jää pysyvästi palvelimelle ja on mahdollista, että se joutuu vääriin käsiin. Palveluun, jossa käytetään sessioita, on siis tehtävä lopeta-toiminto ja neuvottava käyttäjiä aina lopettamaan käyttö sen kautta, eikä sulkemalla selainta.
PHP:ssä sessio saadaan tuhottua session_destroy()-funktiolla, joka tuhoaa aina kutsuttaessa kaikki sessiomuuttujat. Vanhemmissa PHP:n versioissa (PHP 4.0.6 tai vanhempi, jossa on käytössä $_SESSION-muuttujan tilalla $HTTP_SESSION_VARS-muuttuja) voi käyttää session_unset()-funktiota. Kummallakaan funktiolla ei ole parametreja. Yksittäisen sessiomuuttujan voi tuhota unset()-funktiolla, esimerkiksi seuraavasti:
unset($_SESSION['nimi']);
Sessioiden oletusarvot
.htaccess-tiedostossa voi seuraavilla riveillä määrätä sessioihin liittyviä asetuksia:
# Käynnistetään sessio automaattisesti ilman session_start()-funktiota.
# Näin käytettynä ei voida tallentaa sessioon olioita, koska luokkaa ei
# ehdittäisi määritellä ennen sessiomuuttujien alustamista!
php_value session.auto_start 1
# Käytetäänkö evästeitä vai ei.
php_value session.use_cookies 1
# Minne sessiot tallennetaan.
# Ei tarvi normaalisti määritellä.
php_value session.save_path '/home3/368/anjoekon/public_html/php/sessiot'
# Kertoo montako sekuntia sessio pidetään elossa viimeisen sivukäynnin jälkeen.
php_value session.gc_maxlifetime 1800
Esimerkki sessioiden käytöstä
Asetetaan ensin sessiomuuttujat (esimerkiksi aseta.php):
<?php
// aloitetaan sessio
session_start();
// määritetään sessiomuuttujat
$_SESSION["nimi"] = "Antti";
$_SESSION["pyora"] = "Cannondale";
?>
Käytetään sessiomuuttujia (esimerkiksi index.php):
<?php
// aloitetaan sessio
session_start();
// luetaan sessiomuuttujat
$nimi = $_SESSION["nimi"];
$pyora = $_SESSION["pyora"];
// tulostetaan tiedot
echo 'Henkilön '.$nimi.' pyörän merkki on '.$pyora.'.'."\n";
?>
Sessiomuuttujat voitaisiin tuhota seuraavasti (esimerkiksi tuhoa.php):
<?php
// aloitetaan sessio
session_start();
// poistetaan sessiomuuttujat
unset($_SESSION["nimi"]);
unset($_SESSION["pyora"]);
// toinen tapa kaikkien tuhoamiselle
session_destroy();
?>
Tiedostojen lataus palvelimelle
WWW-lomake tiedoston latauksessa
WWW-lomakkeen avulla voidaan siirtää myös paikallisia tiedostoja palvelimelle. Tätä varten on lomakkeella oltava tiedostokenttä. Se määritellään XHTML-koodissa antamalla input-elementin type-attribuutille arvo "file". Tiedostoja siirrettäessä täytyy lomakkeen käyttää POST-metodia tietojen välittämiseen. Lisäksi lomake-elementin (form) enctype-attribuutille täytyy määrittää arvo "multipart/form-data". Muuten tiedoston siirto ei onnistu. Alla on esimerkki tiedoston siirtävän lomakkeen XHTML-koodista.
<form action="jokusivu.php" method="post" enctype="multipart/form-data">
<p>
<input type="hidden" name="MAX_FILE_SIZE" value="30000" />
<input type="file" name="tiedosto" />
</p>
<p>
<input type="submit" value="Siirrä" />
</p>
</form>
Lomakkeelle voidaan laittaa esimerkin mukainen MAX_FILE_SIZE-niminen piilokenttä, jolle annetaan tavuina suurin sallittu siirrettävän tiedoston koko. PHP-tulkki hoitaa silloin automaattisesti asetetun kokorajoituksen siten, että tiedoston siirto palvelimelle ei onnistu, jos käyttäjän valitseman tiedoston koko ylittää rajoituksen. Kannattaa ottaa huomioon, että myös PHP:n asetukset vaikuttavat sallittuun tiedoston maksimikokoon. Oletusasetuksissa PHP sallii yleensä korkeintaan 2 Mt:n tiedoston siirron palvelimelle. Hakemistoon, johon tiedostot siirretään, täytyy muistaa laittaa myös kirjoitusoikeudet päälle. Jos mahdollista, kyseinen hakemisto tulisi olla tietoturvasyistä sellainen, ettei siihen pääse käsiksi suoraan WWW:n kautta.
Ladatun tiedoston käsittely PHP:ssä
PHP kirjoittaa tiedoston latauksen onnistuessa tiedoston ensin tulkin asetuksissa määriteltyyn tilapäiskansioon. Ohjelmoijan tehtäväksi jää siirtää tiedosto palvelimella haluttuun paikkaan. PHP muodostaa automaattisesti WWW-lomakkeelta ladatun tiedoston tiedoista esimääritellyn taulukkotyyppisen muuttujan $_FILES. $_FILES-muuttuja sisältää seuraavat tiedot (['tiedosto'] viittaa lomakkeen tiedostokentän name-attribuuttiin):
- $_FILES['tiedosto']['name'] sisältää tiedoston alkuperäisen nimen ilman hakemistopolkua.
- $_FILES['tiedosto']['tmp_name'] sisältää palvelimelle kirjoitetun tilapäistiedoston hakemistopolkuineen.
- $_FILES['tiedosto']['size'] sisältää tiedoston koon tavuina.
- $_FILES['tiedosto']['type'] sisältää tiedoston sisällön tyypin, mikäli selain on lähettänyt tiedon siitä, esim. "image/gif".
- $_FILES['tiedosto']['error'] sisältää tiedon tiedoston siirrossa tapahtuneesta virheestä. Tietoa virheilmoituksesta voit katsoa PHP.net-sivustolta.
Alla on esimerkki tiedoston vastaanottamisesta PHP:n avulla:
<?php
$polku = "tiedostot/".$_FILES['tiedosto']['name'];
if(move_uploaded_file($_FILES['tiedosto']['tmp_name'], $polku)) {
echo "<p>Tiedoston siirto palvelimelle onnistui!</p>";
} else {
// Tulostetaan asianmukaiset virheilmoitukset.
}
?>
Esimerkissä käytetään move_uploaded_file()-funktiota tiedoston siirtämiseen palvelimelle. Funktio palauttaa false, jos tiedosto ei ole validi lomakkeelta ladattu tiedosto tai tiedoston siirto palvelimelle ei onnistu. Tiedosto siirretään siis onnistuneessa tapauksessa sivun oman hakemiston alla olevaan "tiedostot"-nimiseen hakemistoon. Funktion epäonnistuessa on hyvä tutkia virheen syy ja antaa siitä asianmukainen palaute. Virheen syy voi olla esimerkiksi liian suuri tiedosto.
Haluttaessa voidaan ensin tutkia is_uploaded_file()-funktiolla, onnistuisiko valitun tiedoston siirto palvelimelle. Se tekee siis samanlaisen tarkistuksen kuin move_uploaded_file(), mutta ei vielä siirrä itse tiedostoa.
Samassa yhteydessä (ennen tiedoston varsinaista siirtämistä) on yleensä tarpeen tehdä muitakin tarkistuksia tiedostolle. Jos esimerkiksi haluttiin siirtää kuvatiedosto, on hyvä tutkia onko tiedostopääte oikeanlainen (esimerkiksi .jpg, .gif tai .png). Tutkimiseen voisi käyttää avuksi strrpos()- ja substr()-funktioita. Lisäksi olisi hyvä tutkia, onko tiedoston tyyppi ($_FILES['tiedosto']['type']) joku kuvatyypeistä (jos selain on lähettänyt tiedon tiedoston tyypistä).
Hyödyllisiä funktioita tiedostojen siirrossa
is_uploaded_file()
Tarkistaa, onko parametrina annettu tiedosto kelvollinen WWW-lomakkeen kautta palvelimelle ladattu tiedosto. Parametrina annetaan polku tilapäistiedostoon, jonka PHP kirjoittaa palvelimelle tiedoston latauksen yhteydessä, esim. $_FILES['tiedosto']['tmp_name']. Palautusarvo on true tai false.
move_uploaded_file()
Tekee samanlaisen tarkistuksen kuin is_uploaded_file() ja siirtää sen lisäksi tiedoston haluttuun paikkaan. Parametreina annetaan tilapäistiedoston polku ja polkuineen tiedosto, johon tilapäistiedosto kirjoitetaan. Funktio palauttaa false, jos annettu tilapäistiedosto ei ole kelvollinen WWW-lomakkeen kautta palvelimelle ladattu tiedosto, tai jos tiedoston siirto ei onnistu. Katso esimerkki edellisestä luvusta tältä sivulta.
Tiedostojen käsittely
Tiedoston avaaminen
Tiedoston avaus onnistuu fopen()-funktiolla. Funktiolle täytyy lisäksi määritellä, mitä tarkoitusta varten tiedosto avataan. Mahdollisia vaihtoehtoja ovat seuraavat:
- r = Tiedosto avataan vain lukemista varten.
- r+ = Avataan tiedosto lukemista ja kirjoittamista varten. Tiedostoon kirjoitus/lukeminen alkaa tiedoston alusta.
- w = Tiedosto avataan vain kirjoitusta varten. Vanha tiedosto tuhotaan tai ellei tiedostoa ole olemassa, PHP luo sen.
- w+ = Avataan tiedosto lukemista ja kirjoittamista varten. Tiedosto tyhjennetään ja kirjoitus/lukeminen alkaa tiedoston alusta. Jos tiedostoa ei ole, PHP luo sen.
- a = Tiedosto avataan vain kirjoitusta varten. Kirjoitus alkaa tiedoston lopusta. Jos tiedostoa ei ole, PHP luo sen.
- a+ = Avataan tiedosto lukemista ja kirjoittamista varten. Kirjoitus/lukeminen alkaa tiedoston lopusta. Jos tiedostoa ei ole, PHP luo sen.
$tiedosto = fopen("tiedosto.txt", "r"); // avataan tiedosto lukemista varten
Tiedoston sulkeminen
Tiedosto voidaan sulkea fclose()-funktiolla. Tosin kaikki avatut tiedostot suljetaan automaattisesti PHP-skriptin suorituksen jälkeen, mutta on silti suositeltavaa sulkea avoimet tiedostot sitä mukaa, kun niitä ei enää tarvita.
fclose($tiedosto); // suljetaan edellisessä esimerkissä avattu tiedosto
Tiedostosta lukeminen
Tiedoston voi lukea joko kerralla muuttujaan, rivi kerrallaan muuttujaan tai merkki kerrallaan muuttujaan.
Tiedosto kerralla muuttujaan
file()-funktiolla voi lukea tiedoston kerralla taulukkomuuttujaan. Taulukkomuuttuja saa arvokseen tiedoston rivit yksi kerrallaan. Jokainen rivi päättyy rivinvaihtoon (järjestelmästä riippuen esimerkiksi \n), joten voi olla tarpeen poistaa ylimääräiset merkit trim()-funktiolla. file()-funktiota käytettäessä tiedostoa ei tarvitse avata eikä sulkea erikseen.
$tiedot = file("tiedosto.txt");
/* $tiedot-muuttujan sisältö:
$tiedot[0] = Ensimmäinen rivi
$tiedot[1] = Toinen rivi
$tiedot[n] = n:s rivi */
Tiedosto on mahdollista lukea kerralla merkkijonomuuttujaan
fread()-funktiolla.
Toisin kuin file()-funktiota käytettäessä,
tiedosto pitää avata ensin lukemista varten. Apuna tarvitsee usein myös
filesize()-
ja explode()-funktioita.
$tiedosto = fopen("tiedosto.txt", "r"); // avataan tiedosto
$tiedot = fread($tiedosto, filesize("tiedosto.txt")); // luetaan koko tiedosto merkkijonomuuttujaan
fclose($tiedosto); // suljetaan tiedosto
$rivit = explode("\n", $tiedot); // viedään tiedosto taulukkoon riveittäin (file() tekisi suoraan...)
foreach ($rivit as $rivi) { // toki voitaisiin pilkkoa jonkun muunkin kuin rivinvaihtomerkin mukaan
echo "$rivi\n"; // tehdään jotain (esimerkiksi tulostetaan) pilkotuille palasille
}
Tiedosto riveittäin muuttujaan
fgets()-funktiolla voi lukea tiedostosta rivin kerrallaan. Apuna tarvitsee feof()-funktiota, joka palauttaa TRUE, kun tiedoston loppu tulee vastaan, muutoin funktio palauttaa arvon FALSE.
$tiedosto = fopen("tiedosto.txt", "r"); // avataan tiedosto
while(!feof($tiedosto)) {
$rivi = fgets($tiedosto, 4096); // rivi kerrallaan, korkeintaan 4096 tavua
echo $rivi."\n";
}
fclose($tiedosto); // suljetaan tiedosto
Tiedosto merkeittäin muuttujaan
fgetc()-funktiolla voi lukea tiedostosta merkin kerrallaan. Funktio toimii lähes samalla tavalla kuin fgets()-funktio.
$tiedosto = fopen("tiedosto.txt", "r"); // avataan tiedosto
while(!feof($tiedosto)) {
$merkki = fgetc($tiedosto); // merkki kerrallaan
echo $merkki."\n";
}
fclose($tiedosto); // suljetaan tiedosto
Tiedostoon kirjoittaminen
fwrite()-funktiolla voidaan kirjoittaa suoraan tiedosto-osoittimeen (pointer). Tiedosto täytyy ensin muistaa avata kirjoitustilaan. Lisäksi tiedostolle täytyy muistaa antaa riittävät kirjoitusoikeudet.
Jos mahdollista, tiedosto, johon kirjoitetaan tulisi olla tietoturvasyistä sellaisessa hakemistossa, johon ei pääse käsiksi suoraan WWW:n kautta.
$tiedosto = fopen("tiedosto.txt", "w");
$teksti = "Esimerkkitekstiä tiedostoon.";
fwrite($tiedosto, $teksti);
fclose($tiedosto);
Tiedoston lukitseminen
flock()-funktiolla voidaan lukita tiedosto niin, ettei kukaan/mikään muu (esimerkiksi toinen PHP-skripti) voi muuttaa sitä sen ollessa auki. Tiedosto on hyvä lukita ainakin tiedostoon kirjoittamisen ajaksi. Mahdollisia lukitusvaihtoehtoja ovat seuraavat:
- LOCK_SH (tai 1) - lukitsee tiedoston lukemista varten.
- LOCK_EX (tai 2) - lukitsee tiedoston kirjoittamista varten.
- LOCK_UN (tai 3) - vapauttaa tiedoston lukituksen.
$tiedosto = fopen("tiedosto.txt", "w+"); // avataan tiedosto
if(flock($tiedosto, LOCK_EX)) { // lukitus kirjoitusta varten
fwrite($tiedosto, "Tekstiä tiedostoon..."); // kirjoitetaan tiedostoon
flock($tiedosto, LOCK_UN); // vapautetaan lukitus
} else {
echo "<p>Lukitus ei onnistunut!</p>";
}
fclose($tiedosto); // suljetaan tiedosto
Hyödyllisiä funktioita tiedostoja käsitellessä
- fseek() - Osoittimen siirtäminen haluttuun kohtaan tiedostoa.
- rewind() - Osoittimen siirtäminen tiedoston alkuun.
- is_file() - Tarkistaa että kyseessä on tiedosto.
- is_writeable() - Tarkistaa että tiedostoon kirjoittaminen onnistuu.
- is_readable() - Tarkistaa voidaanko tiedostosta lukea.
- file_exists() - Tarkistaa tiedoston olemassaolon.
- ftruncate() - Tiedoston lyhentäminen.
- md5() - Tiedon salaaminen (esimerkiksi salasanat on hyvä tallentaa salattuina).
Edelleenohjaus
Käyttäjä voidaan edelleenohjata toiselle sivulle header()-funktiolla, jolle annetaan parametrina "Location"-arvo. Edelleenohjausta tarvitaan yleensä esimerkiksi sivuston kirjautumisen toteutuksessa. header()-funktiota tulee kutsua aina ennen kuin sivulla tulostetaan mitään XHTML-koodia, koska on kyse HTTP-otsikkotietojen muokkauksesta.
header("Location: http://appro.mit.jyu.fi/"); // uudelleenohjaus sivulle http://appro.mit.jyu.fi/
Lisätietoa
- Evästeet - PHP.net
- Evästeet - Mureakuha
- Evästeet - Ohjelmointiputka
- Sessiot - PHP.net
- Sessiot - Mureakuha
- Sessiot - Ohjelmointiputka
- Tiedostojen lataus - PHP.net
- Tiedostojen käsittely - PHP.net
- Tiedostojen käsittely - Mureakuha
- Tiedostojen käsittely - Ohjelmointiputka
Käyttäjien kommentit