Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 2 - Práce s textovými soubory v PHP

V předchozí lekci, Úvod do práce se soubory v PHP, jsme si ujasnili, jaké typy souborů existují a jak pracovat s cestami k těmto souborům. V této lekci se podíváme také na to, jak pracovat s nestrukturovaným prostým textem v jazyce PHP.

Přestože se v této lekci budeme zaměřovat primárně na práci s nestrukturovanými textovými soubory, tak funkce, které si zde ukážeme, budeme využívat i v dalších lekcích při práci se strukturovanými soubory.

Způsoby čtení a zápisu souborů v PHP

V PHP lze číst a zapisovat soubory dvěma způsoby:

  • pomocí jednoúčelových funkcí a
  • pomocí tzv. resources.

První způsob má výhodu ve své jednoduchosti a rychlosti. PHP má funkce, které při svém zavolání přečtou či zapíšou celý obsah souboru. Kdybychom ale například chtěli pracovat po částech s velkými soubory nebo přímo při čtení/zápisu pracovat se souborem CSV, je tato abstrakce na škodu. V takovém případě využíváme tzv. resources. S druhým způsobem se však seznámíme až v další lekci.

Práce se soubory pomocí jednoúčelových funkcí

Nyní se seznámíme s jednoúčelovými funkcemi.

file_put_contents() – zápis řetězce do souboru

Předtím, než budeme soubor číst, si ukážeme, jak takový soubor vytvořit a jak do něj zapsat nějaký text. K zápisu řetězce (string) do souboru slouží v PHP funkce file_put_contents(). Jako první argument přijímá cestu k zapisovanému souboru a jako druhý argument onen textový řetězec, který chceme zapsat. Jestliže cílový soubor neexistuje, pokusí se ho PHP vytvořit:

$soubor = "muj_text.txt";
$text = "Ahoj!<br />\nToto je text, který se objeví v našem souboru :-)";

file_put_contents($soubor, $text);

Obsah souboru muj_text.txt by po spuštění skriptu měl být takovýto:

Ahoj!<br />
Toto je text, který se objeví v našem souboru :-)

Víme tedy, že sekvence \n udělala v textovém souboru nový řádek, stejně jako tag <br /> vytvoří nový řádek v prohlížeči.

Ošetření chyb

Během vykonávání programu může dojít k chybám a u práce se soubory tomu není jinak. Funkce file_put_contents() vrací počet bajtů, které zapsala, ale když dojde k chybě, vrací booleovskou hodnotu false. V příkladu výše by měl kód pro zápis do souboru vypadat správně takto:

$zapsano = file_put_contents($soubor, $text);

if ($zapsano === FALSE) {
  echo("Při zápisu do souboru nastala chyba!");
} else {
  echo("Zápis do souboru se povedl!<br />Počet zapsaných bajtů: "), $zapsano;
}

V prohlížeči by se nám mělo ukázat toto:

file_put_contents()
file_put_conten­ts.php

V případě chyby zase toto:

file_put_contents() - ERROR
file_put_conten­ts.php

Můžeme si všimnout, že na porovnávání návratové hodnoty a booleovské hodnoty false používáme operátor ===, neboli tzv. strict comparison operator. Ten určuje, že porovnávané hodnoty musí být nejen "stejné", ale musí být i stejného datového typu. To je důležité, protože funkce file_put_contents() by mohla "zapsat" i 0 bajtů, což nemusí nutně značit chybový stav. V případě použití operátoru == (tzv. loose comparison operator), který asi už dobře známe, by PHP jakožto slabě typovaný jazyk vyhodnocovalo, že 0 je false. A těžko nalezitelná chyba v programu by byla na světě :-)

Chyba zápisu kvůli nedostatečných oprávnění

Pokud si skript spustíme na vlastním serveru a skončí s chybou, pravděpodobně skript nemá právo do souboru zapisovat. Jestliže soubor již existuje, musíme uživatelskému účtu, pod kterým PHP běží, přidělit k souboru oprávnění pro zápis. Pokud soubor ještě neexistuje, musí uživatel dostat práva k zápisu do složky, ve které se bude soubor vytvářet. Pokud náš server používá operační systém Linux, problematika oprávnění je probírána v lekci Linuxový terminál (Bash) - Oprávnění, instalace a procesy v kurzu Základy Linuxu :-)

Připisování obsahu do souboru, tzv. append režim

Jestliže už soubor existuje a je v něm nějaký obsah, funkce file_put_contents() ho standardně vymaže a vytvoří soubor nový. Kdybychom tvořili například návštěvní knihu, bylo by toto chování nežádoucí. Funkce ale nabízí tzv. append režim, kdy platí, že se nový obsah přidá na konec toho existujícího. Do tohoto režimu se můžeme dostat tak, že funkci jako třetí argument předáme konstantu FILE_APPEND:

$zapsano = file_put_contents($soubor, $text, FILE_APPEND);

Zamykání souborů

Kdybychom měli na webu hodně návštěvníků zároveň a každý zapisoval něco do souboru, mohlo by se stát, že by zápis do stejného souboru proběhl vícekrát ve stejnou chvíli a náš soubor by se poškodil. Tomuto můžeme předejít tím, že funkci předáme jako třetí argument konstantu LOCK_EX. Operace zápisu bude takto atomická (tzn. veškeré zápisy budou probíhat po sobě, nikoliv najednou):

$zapsano = file_put_contents($soubor, $text, LOCK_EX);

Kdybychom chtěli zkombinovat append režim se zamykáním, obě konstanty spojíme pomocí bitového operátoru OR (|):

$zapsano = file_put_contents($soubor, $text, FILE_APPEND | LOCK_EX);

file_get_contents() – přečtení souboru do řetězce

Soubor již máme vytvořený, a tak jej můžeme přečíst. Funkce file_get_contents() vezme obsah souboru, jehož cestu jí předáme v prvním argumentu, celý ho přečte a vrátí nám ho jako řetězec. Stačí ji předat jediný argument, který je název souboru. Vrací buď přečtená data jako řetězec, nebo false v případě chyby:

$soubor = "muj_text.txt";

$obsahSouboru = file_get_contents($soubor);

if ($obsahSouboru === FALSE) {
  echo("Při čtení souboru došlo k chybě!");
} else {
  echo("Soubor byl úspěšně přečten!<br />Obsah souboru:<br />"), $obsahSouboru;
}

Výstup skriptu bude vypadat takto:

file_get_contents()
file_get_conten­ts.php

Vzhledem k tomu, že prázdný řetězec je také standardně brán jako false, použijeme i zde na kontrolu chyby operátor ===.

file() – přečtení souboru po řádcích do pole

Funkce file() pracuje stejně jako file_get_contents() s tím rozdílem, že obsah souboru nepřečte do řetězce, ale rozdělí jej po řádcích a vrátí pole těchto řádků. Kdybychom například v souboru měli uložené komentáře k našemu článku a každý měli na samostatném řádku, tato funkce by se nám hodila více, než file_get_contents(), protože bychom pravděpodobně chtěli jednotlivé komentáře před výpisem obalit do nějakého rámečku apod.:

$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 />";
  }
}

Funkci echo() můžeme volat i bez závorek, v případě výše se nám to může vyplatit, nemusíme psát hodně závorek.

Výstup:

funkce file()
file.php

readfile() – vypsání souboru přímo do prohlížeče

Může se stát, že obsah souboru nebudeme chtít zpracovávat, ale pouze vypsat návštěvníkovi našich webových stránek. Výhoda funkce readfile() oproti dříve zmiňovaným je ta, že může pracovat i s velmi velkými soubory. Odpadá zde totiž mezikrok v podobě zapsání textu do proměnné (= do paměti RAM), která má oproti diskům omezenou velikost. Kdybychom takto vypisovali například databázi, která má několik gigabajtů, tak by nám to s dříve zmiňovanými funkcemi neprošlo, zatímco s funkcí readfile() ano :-):

$soubor = "muj_text.txt";

$bytu = readfile($soubor);

if ($obsahSouboru === FALSE) {
  echo("Při vypisování souboru došlo k chybě!");
} else {
  echo("<br /><br />Soubor byl vypsán!<br />Vypsáno bajtů: "), $bytu;
}

Výstup:

Funkce readfile()
readfile.php

Jak vidíme, tak v proměnné $bytu budeme mít pouze počet přečtených bajtů, zatímco samotný obsah souboru skončí v prohlížeči :-)

Zdrojové kódy příkladů z této lekce naleznete ke stažení níže.

V následujícím cvičení, Řešené úlohy k 1.-2. lekci práce se soubory v PHP, si procvičíme nabyté zkušenosti z předchozích lekcí.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 55x (3.06 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP

 

Předchozí článek
Úvod do práce se soubory v PHP
Všechny články v sekci
Soubory a práce s nimi v PHP
Přeskočit článek
(nedoporučujeme)
Řešené úlohy k 1.-2. lekci práce se soubory v PHP
Článek pro vás napsal Vít Labuda
Avatar
Uživatelské hodnocení:
25 hlasů
Aktivity