Evästeet, sessiot ja tiedostot - Luento 9

Luentotaltiointi

Ongelmia videon katselussa?

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

Kaaviokuva sessioiden toiminnasta

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 &amp;

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):

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:

$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:

$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ä

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

Käyttäjien kommentit

Kommentoi tätä sivua Lisää uusi kommentti
Kurssimateriaalien käyttäminen kaupallisiin tarkoituksiin tai opetusmateriaalina ilman lupaa on ehdottomasti kielletty!
http://appro.mit.jyu.fi/sovellukset/luennot/luento9/
© Antti Ekonoja (anjoekon@jyu.fi) <http://users.jyu.fi/~anjoekon/>
Tommi Lahtonen (tommi.j.lahtonen@jyu.fi) <http://hazor.iki.fi/>
Jukka Mäntylä (jmantyla@iki.fi) <http://www.iki.fi/jmantyla/>
2008-04-17 14:15:41
Informaatioteknologia - Jyväskylän yliopiston IT-tiedekunta ja avoin yliopisto