2. diel - Práca s textovými súbormi v PHP
V predchádzajúcej lekcii, Úvod do práce so súbormi v PHP , sme si ujasnili, aké typy súborov existujú a ako pracovať s cestami k týmto súborom. V tejto lekcii sa pozrieme aj na to, ako pracovať s neštruktúrovaným obyčajným textom v jazyku PHP.
Hoci sa v tejto lekcii budeme zameriavať primárne na prácu s neštruktúrovanými textovými súbormi, tak funkcie, ktoré si tu ukážeme, budeme využívať aj v ďalších lekciách pri práci so štruktúrovanými súbormi.
Spôsoby čítania a zápisu súborov v PHP
V PHP možno čítať a zapisovať súbory dvoma spôsobmi:
- pomocou jednoúčelových funkcií a
- pomocou tzv. resources.
Prvý spôsob má výhodu vo svojej jednoduchosti a rýchlosti. PHP má funkcie, ktoré pri svojom zavolaní prečítajú či zapíšu celý obsah súboru. Keby sme ale napríklad chceli pracovať po častiach s veľkými súbormi alebo priamo pri čítaní / zápise pracovať so súborom CSV, je táto abstrakcia na škodu. V takom prípade využívame tzv. Resources. S druhým spôsobom sa však zoznámime až v ďalšej lekcii.
Práca so súbormi pomocou jednoúčelových funkcií
Teraz sa zoznámime s jednoúčelovými funkciami.
file_put_contents()
- zápis reťazca do súboru
Predtým, než budeme súbor čítať, si ukážeme, ako takýto súbor
vytvoriť a ako doň zapísať nejaký text. K zápisu reťazca (stringu) do
súboru slúži v PHP funkcie file_put_contents()
. Ako prvý
argument prijíma cestu k zapisovanému súboru a ako druhý argument onen
textový reťazec, ktorý chceme zapísať. Ak cieľový súbor neexistuje,
pokúsi sa ho PHP vytvoriť:
$soubor = "muj_text.txt"; $text = "Ahoj!<br>\nToto je text, který se objeví v našem souboru :-)"; file_put_contents($soubor, $text);
Obsah súboru muj_text.txt
by po spustení skriptu mal byť
takýto:
Ahoj!<br /> Toto je text, který se objeví v našem souboru :-)
Ošetrenie chýb
Počas vykonávania programu môže dôjsť k chybám au práce so súbormi
tomu nie je inak. Funkcia file_put_contents()
vracia počet bajtov,
ktoré zapísala, ale keď dôjde k chybe, vracia boolean false
. V
príklade vyššie by mal kód pre zápis do súboru vyzerať správne
takto:
$navrat = file_put_contents($soubor, $text); if($navrat === FALSE) { echo "Pří zápisu do souboru nastala chyba!"; } else { echo "Zápis do souboru se povedl!<br />Počet zapsaných bajtů: ", $navrat; }
V prehliadači by sa nám malo ukázať toto:
V prípade chyby zase toto:
Môžeme si všimnúť, že na porovnávanie návratovej hodnoty a boolovské
hodnoty false
používame operátor ===
, alebo tzv.
Strict comparison operator. Ten určuje, že porovnávané
hodnoty musia byť nielen "rovnaké", ale musí byť aj rovnakého
dátového typu. To je dôležité, pretože funkcia
file_put_contents()
by mohla "zapísať" i 0 bajtů
,
čo nemusí nutne značiť chybový stav. V prípade použitia operátoru
==
(tzv. Loose comparison operator), ktorý asi
už dobre poznáme, by PHP, ako slabo typizovanom jazyk,
vyhodnocovalo, že 0 == false
a ťažko hledatelná chyba v
programe by bola na svete.:-)
Chyba zápisu kvôli nedostatočných oprávnení
Pokiaľ si skript spustíme na vlastnom serveri a skončí s chybou, pravdepodobne skript nemá právo do súboru zapisovať. Ak súbor už existuje, musíme užívateľskému účtu, pod ktorým PHP beží, prideliť k súboru oprávnenia pre zápis. Ak súbor ešte neexistuje, musí užívateľ dostať práva na zápis do zložky, v ktorej sa bude súbor vytvárať. Ak náš server používa operačný systém Linux, problematika oprávnenia je preberaná v lekcii " Linuxový terminál (Bash) - Oprávnenia, inštalácia a procesy " v kurze " Základy Linuxu)
Pripisovanie obsahu do súboru, tzv. append režim
Ak už súbor existuje a je v ňom nejaký obsah, funkcia
file_put_contents()
ho štandardne vymaže a
vytvorí súbor nový. Keby sme tvorili napríklad návštevnú
knihu, bolo by toto správanie nežiaduce. Funkcia ale ponúka tzv.
Append režim, kedy platí, že sa nový obsah pridá na koniec
toho existujúceho. Do tohto režimu sa môžeme dostať tak, že funkciu ako
tretí argument odovzdáme konštantu FILE_APPEND
:
$navrat = file_put_contents($soubor, $text, FILE_APPEND);
Zamykanie súborov
Keby sme mali na webe veľa návštevníkov zároveň a každý zapisoval
niečo do súboru, mohlo by sa stať, že by zápis do rovnakého súboru
prebehol viackrát v rovnakej chvíli a náš súbor by sa
poškodil. Tomuto môžeme predísť tým, že funkciu odovzdáme ako
tretí argument konštantu LOCK_EX
. Operácia zápisu bude takto
atomická (tzn. Všetky zápisy budú prebiehať po sebe, nie
naraz):
$navrat = file_put_contents($soubor, $text, LOCK_EX);
Keby sme chceli skombinovať append režim so zamykaním, obe konštanty
spojíme pomocou bitového operátora OR
(|
):
$navrat = file_put_contents($soubor, $text, FILE_APPEND | LOCK_EX);
file_get_contents()
- prečítanie súboru do reťazca
Súbor už máme vytvorený, a tak ho môžeme prečítať. Funkcia
file_get_contents()
vezme obsah súboru, ktorého cestu jej
odovzdáme v prvom argumente, celý ho prečíta a vráti nám ho ako reťazec.
Stačí ju odovzdať jediný argument, ktorý je názov súboru. Vracia buď
prečítané dáta ako reťazec, alebo false
v prípade chyby:
$soubor = "muj_text.txt"; $text = file_get_contents($soubor); if($text === FALSE) { echo "Při čtení souboru došlo k chybě!"; } else { echo "Soubor byl úspěšně přečten!<br />Obsah souboru:<br />", $text; }
Výstup skriptu bude vyzerať takto:
Vzhľadom k tomu, že prázdny reťazec je tiež štandardne braný ako
false
, použijeme aj tu na kontrolu chyby operátor
===
.
file()
-
prečítanie súboru po riadkoch do poľa
Funkcia file()
pracuje rovnako ako
file_get_contents()
s tým rozdielom, že obsah súboru neprečíta
do reťazca, ale rozdelí ho po riadkoch a vráti pole týchto
riadkov. Keby sme napríklad v súbore mali uložené komentáre k
nášmu článku a každý mali na samostatnom riadku, táto funkcia by sa nám
hodila viac, než file_get_contents()
, pretože by sme
pravdepodobne chceli jednotlivé komentáre pred výpisom obaliť do nejakého
rámčeka pod .:
$soubor = "muj_text.txt"; $radky = file($soubor); if($radky === FALSE) { echo "Při čtení souboru došlo k chybě!"; } else { foreach($radky as $i => $radek) { echo "Řádek č. ", ($i + 1), ": ", $radek, "<br />"; } }
výstup:
readfile()
-
vypísanie súboru priamo do prehliadača
Môže sa stať, že obsah súboru nebudeme chcieť spracovávať, ale iba
vypísať návštevníkovi našich webových stránok. Výhoda funkcie
readfile()
oproti predtým spomínaným je tá, že môže
pracovať aj s veľmi veľkými súbormi. Odpadá tu totiž medzikrok v
podobe zapísanie textu do premennej (= do pamäte RAM), ktorá má oproti
diskom obmedzenú veľkosť. Keby sme takto vypisovali napríklad databázu,
ktorá má niekoľko gigabajtov, tak by nám to s predtým spomínanými
funkciami neprešlo, zatiaľ čo s funkciou readfile()
áno:-)
:
$soubor = "muj_text.txt"; $navrat = readfile($soubor); if($navrat === FALSE) { echo "Při vypisování souboru došlo k chybě!"; } else { echo "<br /><br />Soubor byl vypsán!<br />Vypsáno bajtů: ", $navrat; }
výstup:
Ako vidíme, tak v premennej $navrat
budeme mať iba počet
prečítaných bajtov, zatiaľ čo samotný obsah súboru skončí v
prehliadači:-)
Zdrojové kódy príkladov z tejto lekcie nájdete na stiahnutie nižšie.
V nasledujúcom cvičení, Riešené úlohy k 1.-2. lekciu práca so súbormi v PHP, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 59x (3.06 kB)
Aplikácia je vrátane zdrojových kódov v jazyku PHP