Kirjoittaja: Antti Laaksonen (2003).
⚠ Huomio! Tämä opas on vanhentunut. Oppaan sisältöön ei voi enää luottaa. Opas on säilytetty vain sen historiallisen arvon vuoksi. ⚠
PHP-skripti suoritetaan palvelimella, minkä ansiosta sillä on pääsy myös palvelimen tiedostoihin. Tämä opas käsittelee tiedostojen lukemista ja kirjoittamista. Oppaassa tutustutaan myös pariin käyttökelpoiseen tiedostofunktioon sekä menetelmään hakemiston kaikkien tiedostojen läpikäymiseen.
Helppo tapa lukea tiedostosta rivejä on lukea rivit taulukkoon file
-funktiolla. Funktio palauttaa taulukon, joka sisältää tiedoston rivit nollasta alkaen. Esimerkissä tiedosto testi.txt sisältää kolme riviä.
<?php //luetaan tiedosto taulukkoon $tiedosto $tiedosto = file("testi.txt"); //nyt: // $tiedosto[0] = "Ensimmäinen rivi." // $tiedosto[1] = "Toinen rivi." // $tiedosto[2] = "Kolmas rivi." // count($tiedosto) = 3 //tulostetaan rivit for ($i = 0; $i < count($tiedosto); $i++) { echo ($i + 1) . ": " . $tiedosto[$i]; } ?>
Luettava tiedosto voi olla myös toisella palvelimella. Tällöin file
-funktion parametriksi annetaan tiedoston koko URL, kuten http://www.palvelin.fi/sivu.htm
. Taulukon alkiot päättyvät rivinvaihtomerkkiin, mikä voi välillä tuottaa ongelmia esimerkiksi merkkijonojen vertailussa. Funktio trim
poistaa ylimääräiset rivinvaihdot merkkijonon lopusta.
Jos pelkkä lukeminen taulukkoon ei riitä tai tiedostoon halutaan kirjoittaa, tiedosto on avattava fopen
-funktiolla. Funktio palauttaa tiedostotunnisteen, jota käytetään myöhemmin avattuun tiedostoon liittyvien operaatioiden yhteydessä. Tiedosto voi olla, samoin kuin file
-funktion kanssa, myös URL-osoite. Vastaavasti fclose
sulkee avatun tiedoston.
Jos tiedostosta halutaan lukea, se avataan tilassa "r" (read). Funktio fgets
lukee seuraavan rivin tiedostosta. Funktion toinen parametri on rivin maksimipituus. Jos tiedoston rivien määrää ei tiedetä, kannattaa tarkistaa funktiolla feof
ennen jokaista lukukertaa, että rivejä on vielä jäljellä.
<?php //avataan tiedosto lukutilassa $tt = fopen("testi.txt", "r"); //nollataan rivinumerolaskuri $i = 0; //luetaan rivejä, kunnes tiedosto loppuu while (!feof($tt)) { //luetaan seuraava rivi muuttujaan $rivi = fgets($tt, 1024); //tulostetaan rivi rivinumeron kanssa echo "$i: $rivi"; //kasvatetaan laskuria $i++; } //suljetaan tiedosto fclose($tt); ?>
Jos tiedostoon halutaan kirjoittaa, se avataan tilassa "w" (write). Jos tiedostoa ei ole olemassa, se luodaan. Jos tiedosto on jo olemassa, se tyhjennetään. Tiedoston voi avata myös tilassa "a" (append), jolloin kirjoittaminen aloitetaan tiedoston lopusta ja tiedoston vanha tieto ei katoa. Tämän jälkeen tiedostoon voi kirjoittaa funktiolla fwrite
.
<?php //avataan tiedosto kirjoitustilassa $tt = fopen("testi2.txt", "w"); //kirjoitetaan tiedostoon kolme riviä; \n tarkoittaa rivinvaihtoa fwrite($tt, "Rivi 1\n"); fwrite($tt, "Rivi 2\n"); fwrite($tt, "Rivi 3"); //suljetaan tiedosto fclose($tt); ?>
Unix-käyttöjärjestelmässä tiedoston oikeudet (chmod) voivat rajoittaa sen lukemista tai kirjoittamista. Sopiva chmod-arvo riippuu siitä, onko tiedostoa tarkoitus vain lukea vai pitääkö siihen pystyä myös kirjoittamaan. Virheilmoitus "Permission denied" viestii liian tiukoista oikeuksista. FTP-ohjelma sisältää tavallisesti mahdollisuuden muuttaa tiedoston oikeuksia. PHP:stä löytyy myös funktio chmod
tähän tarkoitukseen.
Unixeissa ja Windowseissa käytetään erilaista rivinvaihtoa. Unixin rivinvaihto on \n
(ASCII 10), kun taas Windowsin rivinvaihto on \r\n
(ASCII 13 + ASCII 10). Tämä voi tuottaa ongelmia silloin, kun skriptin luomaa tiedostoa yritetään lukea Windowsin tekstieditorilla: toiset editorit eivät tunnista oikein Unix-rivinvaihtoja. Yhtä kaikki PHP:lle kelpaavat molemmat tavat ilmaista rivinvaihto.
PHP sisältää joukon valmiita funktioita, joiden avulla on mahdollista saada tarkempia tietoja tiedostosta. Funktiot ovat käytössä ainoastaan oman palvelimen tiedostoilla. Tässä listassa on muutamia tavallisimpia funktioita.
file_exists
kertoo, onko tiedostoa olemassa.filesize
palauttaa tiedoston koon tavuina.fileatime
palauttaa ajan, jolloin tiedostoa on viimeksi käytetty.filemtime
palauttaa ajan, jolloin tiedostoa on viimeksi muokattu.Esimerkki tarkistaa tiedoston olemassaolon ja tulostaa sen koon ja muokkausajan. Lisätietoa date-funktion käytöstä on tulossa opassarjan seuraaviin osiin.
<?php //käsiteltävä tiedosto $tiedosto = "testi.txt"; //jatketaan, jos tiedosto on olemassa if (file_exists($tiedosto)) { //luetaan tiedoston koko ja muokkausaika muuttujiin $koko = filesize($tiedosto); $aika = filemtime($tiedosto); //tulostetaan tiedot echo "Tiedoston koko on $koko tavua ja sitä on viimeksi muokattu " . date("d.m.Y", $aika). "."; } else { echo "Tiedostoa ei ole olemassa!"; } ?>
Hakemiston tiedostojen läpikäyminen onnistuu kolmen funktion yhteistyöllä: opendir
, readdir
ja closedir
. Näitä funktioita tarvitaan vaikkapa silloin, kun halutaan luoda hakemistossa olevista kuvatiedostoista automaattisesti päivittyvä kuvagalleria. Aluksi kutsutaan opendir
-funktiota parametrina käsiteltävä hakemisto. Tämän jälkeen readdir
-funktio palauttaa aina seuraavan tiedoston hakemistossa. Lopuksi funktio closedir
sulkee hakemiston.
<?php //avataan hakemisto kuvat $hak = opendir("kuvat/"); //luetaan ensimmäisen tiedoston nimi $nimi = readdir($hak); //jatketaan niin kauan kun $nimi ei ole false while ($nimi) { //tulostetaan tiedoston nimi echo "$nimi\n"; //luetaan seuraavan tiedoston nimi $nimi = readdir($hak); } //suljetaan hakemisto closedir($hak); ?>
Jos opendir
-funktiota kutsutaan parametrilla ".", tiedostoja etsitään siitä hakemistosta, johon skripti on tallennettu (tai oletushakemistosta). Hakemistosta luetaan sekä tiedostot että alihakemistot: funktio is_file
ilmoittaa, jos kyseessä on tiedosto ja is_dir
ilmoittaa, jos kyseessä on hakemisto.
Tiedostofunktiota tarvitsee usein ja niiden käytöstä tuleekin nopeasti arkipäivää PHP-ohjelmoijalle. PHP:n manuaalia kannattaa silmäillä tiedostoihin(kin) liittyvissä asioissa: se sisältää kaikkien tiedostofunktioiden kuvaukset ja myös monia hyödyllisiä esimerkkiskriptejä.
Näillä näkymin oppaita tulee vielä kaksi tai kolme. Vielä käsittelemättä olevia aiheita ovat ainakin funktiot ja luokat, merkkijono- ja päivämääräfunktiot, evästeet sekä MySQL-tietokannan käyttäminen. Seuraava opas ilmestynee parin-kolmen viikon kuluessa.
Antti Laaksonen, 24.4.2003
opendir(), readdir() ja closedir() yhdistelmän sijasta on helpompi käyttää vain glob()-funktiota. :)
Näyttää olevan version 4.3.0 ominaisuuksia, enpä olekaan huomannut moista. Selvästi näppärämpi tapa. Olkoon tässä oppaassa kuitenkin tuo vanhempi yhteensopivuuden vuoksi.
Ihan hyvä, mutta vielä ku oisit pistäny yksittäisten rivien käsittelyä...
Niin, kun mulla on jäänyt tuo tietyn rivin muuttaminen vähän epäselväksi...
Esim. jos tiedostossa on rivejä vaikka neljä, ja niissä lukee:
Moi!
Olen Saasta!
Käyn ohjelmointiputkassa aika usein!
Heippa!
Niin haluan korvata kolmannen rivin vaikka muotoon: "Käyn ohjelmointiputkassa tosi usein!". haluan sen siis korvata niin, ettei sillä tekstillä ole mitään väliä, kun Tumpi joskus jotain semmoista ehdotti että
if ($rivi == "Käyn ohjelmointiputkassa aika usein") {
mutta jos kolmannella rivillä onkin jotain aivan muuta? Pitääkö sen olla jotenkin tyyliin:
if ($rivi == 3) {
tai jotain...?
Tai no.. miksei joku voisi samantien tehdä sille jotain yksinkertasta funktiota, vaikka tyyliin
row_replace($tt, 3, "Käyn ohjelmointiputkassa tosi usein!");
eli tossa on käytössä toi fopen():lla aukaistu tiedosto, $tt, josta korvatan kolmas rivi tekstillä "Käyn ohjelmointiputkassa tosi usein!".
PS: Tais tulla vähän pitkä...
PPS: phpkoodi-tagin hyötykäyttöä :)
Onko tossa phpkoodi-tagissa kenties joku pituusrajoitin tai jotain? ainakin mun koneella toi loppuu hieman lyhyeen...
Niin, putkasssa aina tuppaa koodivinkeistä jäädä pari viimeistä merkkiä pois... ja näköjään nyt tästäkin.
<?php $tiedosto = file("tiedosto.txt"); $tiedosto[2] = "uusi rivi\n"; $fo = fopen("tiedosto.txt", "w"); foreach($tiedosto as $rivi) { fputs($fo, $rivi); } fclose($fo); ?>
tämä koodi korvaa tiedoston "tiedosto.txt" kolmannen rivin sanalla "uusi rivi".
miten tossa ekassa esimerkissä saa ne eri riveille ja ne numerot pois alusta??
sain numerot pois... mut mite ne saa eri riveille
nyt sain toimimaa beeärrällä :)
voiks ton fwrite käskyn perään laittaa muuttujia
esim. fwrite($tt, $uusirivi"\n");
Voi kai
Kyllä voi, koodin tulkkausvaiheessa haetaan muuttujan arvo ja käytetään sitä funktion parametrina.
Jiihaa! Vihdoin opin tiedostoon kirjoittamisen! KIITOS TÄSTÄ OPPAASTA!
Opin tiedostoon kirjoittamisen, mutta miten se hoituisi esimerkiksi palautelomaketta hyväksikäyttäen?
Opin tiedostoon kirjoittamisen, mutta miten se hoituisi esimerkiksi palautelomaketta hyväksikäyttäen?
<html> <head> </head> <body> <form action="tiedostosi.php" method="POST"> <input type="text" value="tekstiä" name="nimi"> <input type="submit" value="Tulosta nimi"> </form> <?php //Otetaan lomakkeesta muuttujat ylös $nimi = $_POST['nimi']; //Nyt kirjotettattaisiin $nimi tiedostoon. ?> </body> </html>
Olisiko whilen sijasta käytännöllisempää käyttää foria?
Tämän ansiosta ratkasin monta viikkoa kiusanneen ongelman :). Hyvä opas!
Utzo kirjoitti:
Opin tiedostoon kirjoittamisen, mutta miten se hoituisi esimerkiksi palautelomaketta hyväksikäyttäen?
Toi kuvagalleria ei oo mikään toimivin ratkaisu koska se tulostaa sivulle pelkän kuvan nimen.
Miten toi tiedostosta hakeminen tehään niin, ettei se lue alihakemistojen nimiä ollenkaan?
Miten tuon kuvagallerian saisi toimimaan jos joku tietää koodin niin vosiko panna tänne vaikka voinhan sen itsekin opetella mutta se oli kuitenkin nopeampaa.
En kyllä arvosta tuota asennetta, mutta jospa innostuisit itse opettelemaan lisää vaikkapa tämän koodinpätkän innoittamana. Yksinkertaisuudessaan saat hakemiston kaikki kuvat näkyviin www-sivuille esim. seuraavalla skriptillä:
<?php foreach(glob("*.jpg") as $filename) { echo "<img src={$filename} /><br />"; } ?>
Siitä sitten vaan jalostamaan. Kuvista kannattaa näyttää thumbnailit ja jos kuvia on paljon niin sivuuttaa ne.
Jos teen profiili.php ja laitan kaikkia profiilit samaan tiedostoon tällä tavalla:
nro|nimi|ikä|kommentti
1|ville|70|Mun nimi on Ville ja mä oon 70v!
2|kalle|12|Mä oon Kalle.
3|ralle|11|Olen melkein 12.
...
niin miten kalle voi vaihtaa kommentiaan? Elikkä miten mä vaihan rivin nro. 2 kommenttia?
Moro!
Voisiko joku auttaa minua? ongelmana on se että tämä ko. koodi toimii kyllä muuten mutta tiedostoon ei tule yhtään mitään:
<!-- laheta.php --> <?php $olemassa = file_exists("testi.php"); if($olemassa) { $tiedosto = fopen("testi.php", "w"); $text = $_POST['teksti']; fwrite($tiedosto, "$text"); fclose($tiedosto); header("Location: index.php?sivu=tiedostot"); } else echo "Tiedostoa ei löydy"; ?>
<!--testi.php--> <form action="laheta.php" method="post"> <textarea name="teksti" rows="10" cols="70"></textarea> <input type="submit" value="Laheta"> </form>
Ja testi.php:n oikeudet 664.
Mikä on vikana, ku tohon teksti kenttään kirjoittaa, niin se teksti ei tallennu? ku se kuitenkin ohjaa sen tonne tiedostot.php:hen?
Edit. Nyt toimmi, ku laitoin oikeudet 777 mutta mitä se vaatii että voi php tiedostoon kirjoittaa?
miten saan sivuni menevän toiseen dokumenttiin ilman, että sivuilla olija painaa jostain linkistä?
Hei kuulkaas, laittakaa ne koodit kooditagien sisään. Selkeytyy aika paljon.
Huomio! Kommentoi tässä ainoastaan tämän oppaan hyviä ja huonoja puolia. Älä kirjoita muita kysymyksiä tähän. Jos koodisi ei toimi tai tarvitset muuten vain apua ohjelmoinnissa, lähetä viesti keskusteluun.