Obsah lekce:
Proces zpracování textového souboru je prozatím ve stavu, kdy nám skript vypíše jednotlivé řádky souboru do prohlížeče. Připomeňme si na úvod současnou situaci. Složku s php skriptem i souborem s daty si můžete stáhnout: zpracovani-souboru-1.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1250" /> <title>Seznam zaměstnanců</title> </head> <body> <?php $nazev_souboru="data/zamestnanci.csv"; if (file_exists($nazev_souboru)) { $soubor=fopen($nazev_souboru, "r"); if($soubor){ while (!feof($soubor)){ $radek = fgets($soubor,5000); print($radek); print("<br />"); } } else { print("Soubor ".$nazev_souboru." se nepodařilo otevřít pro čtení."); } } else { print("Soubor ".$nazev_souboru." neexistuje."); } ?> </body> </html>
Pokusme se podrobně popsat jednotlivé řádky souboru, jejich význam a funkci.
Podívejme se nyní na výsledný výpis dat ze souboru do prohlížeče. Uvědomme si, že bychom si přáli udělat pěknou html stránku, která bude obsahovat nadpis a v tabulce seznam zaměstnanců. Zatím máme v prohlížeči pouze "surová" data (viz obrázek).
Pokusme se popsat vše, co je potřeba v současném výstupu napravit, abychom dosáhli našeho cíle.
Tady bude řešení jednoduché. Data upravíme ručně přímo v csv souboru. Odstraníme středníky z prvního řádku a zcela vymažeme druhý řádek. Vstupní datový soubor tak bude mít na prvním řádku nadpis, na druhém bude hlavička tabulky (tu ponecháme tak jak je) a na dalších řádcích budou jednotlivé řádky tabulky.
V našem skriptu musíme po načtení prvního řádku zobrazit data z něj jako nadpis. Náš cyklus while se tedy musí chovat jinak pro první řádek a jinak pro řádky následující. To vyřešíme tak, že si vytvoříme proměnnou, která nám bude počítat počet zpracovaných řádků souboru. Před cyklem while ji nastavíme na hodnotu nula a po každém průchodu cyklem ji zvýšíme o jedničku (inkrementujeme). Následně přidáme jednoduchou podmínku: "když jsme na prvním řádku souboru (hodnota proměnné $pocetradku je rovna jedné), pak zobraz řádek jako nadpis a pokud ne (jsme na druhém a následujících řádcích), pak zobraz řádek jako řádek tabulky.".
$pocetradku = 0; while (!feof($soubor)){ $pocetradku = $pocetradku + 1; $radek = fgets($soubor,5000); if ($pocetradku == 1) { print("<h1>".$radek."</h1>"); } else { print($radek); print("<br />"); } }
Zbývá zobrazit řádek ze souboru jako řádek tabulky. Nejprve před výpis řádků vložíme značku pro začátek tabulky. Toto musíme udělat nejvýše jednou v momentě, kdy jsme na druhém řádku souboru a ještě jsme řádek nevypsali (nejprve musí být v html kódu značka pro začátek tabulky a teprve potom jednotlivé řádky). Značku pro konec tabulky vložíme za cyklus while.
$pocetradku = 0; while (!feof($soubor)){ $pocetradku = $pocetradku + 1; $radek = fgets($soubor,5000); if ($pocetradku == 1) { print("<h1>".$radek."</h1>"); } else { if ($pocetradku == 2){ print("<table cellspacing=\"0\" cellpadding=\"0\">"); } print($radek); print("<br />"); } } print("</table>");
Podívejme se ještě na zdrojový html kód naší html stránky produkovaný naším skriptem v tomto momentě. Zatím se ještě nejedná o korektní html kód, protože nejsou správně označkovány řádky tabulky.
<body> <h1>Zaměstnanci GJŠ Zlín</h1> <table cellspacing="0" cellpadding="0"> Jméno ;Příjmení;Titul;E-mail;Telefon;Fotografie;Zkratka <br />Eliška;Babíková;;babikova@gjszlin.cz;577007450;babikova.jpg; <br />Radim;Bárta;Mgr.;barta@gjszlin.cz;577007448;barta.jpg;Bár <br />Libuše;Beranová;Ing.;beranova@gjszlin.cz;577007434;beranova.jpg;Ber ... <br />Pavla;Titěrová;Mgr.;titerova@gjszlin.cz;577007458;titerova.jpg;tit <br />Michal;Heczko;Ing.;heczko@gjszlin.cz;;;Hec <br /><br /></table></body> </html>
Víme, že každý řádek html tabulky musí začínat značkou <tr> a končit značkou </tr>. Proto tyto značky vložíme před a za výpis proměnné $radek. Protože budou výsledná data zobrazena jako tabulka, ztrácí značka <br> svůj další za výpisem každého řádku smysl a můžeme ji odstranit.
$pocetradku = 0; while (!feof($soubor)){ $pocetradku = $pocetradku + 1; $radek = fgets($soubor,5000); if ($pocetradku == 1) { print("<h1>".$radek."</h1>"); } else { if ($pocetradku == 2){ print("<table cellspacing=\"0\" cellpadding=\"0\">"); } print("<tr>".$radek."</tr>"); } } print("</table>");
Poslední problém, který zbývá vyřešit je vložení značek pro buňky tabulky do proměnné $radek (provést ono nahrazení popsané výše). Řešení tohoto problému bude obtížnější a věnujeme mu následující kapitolu.
Každému řádku v tabulce tabulkového procesoru odpovídá v textovém souboru jen jeden řádek s tím, že údaje z jednotlivých sloupců jsou v textovém souboru odděleny středníkem (zpravidla). Naším úkolem je po načtení řádku do proměnné $radek nějakým způsobem řádek upravit tak, abychom mohli řádek rozdělit do jednotlivých sloupců html tabulky.
Uvědomme si, co přesně potřebujeme. Musíme sloupce oddělené středníkem přeformátovat do html tak, aby to byly sloupce tabulky. Řešením je provést následující nahrazení:
Jméno;Příjmení;Titul;E-mail;Telefon;Fotografie;Zkratka
nahradit za
<td>Jméno</td><td>Příjmení</td><td>Titul</td><td>E-mail</td><td>Telefon</td><td>Fotografie</td><td>Zkratka</td>
Stačil by tedy nějaký jednoduchý příkaz, který v proměnné provede nahrazení středníků značkami pro konec a začátek nové buňky tabulky. Došlo by vlastně k jednoduchému pokynu: "Nahraď v proměnné $radek znak ';' za řetězec '</td><td>'."
Pokuste se (například pomocí Google) nalézt na Internetu informaci, zda existuje nějaký způsob jak v PHP nahradit nějakou část řetězce jiným řetězcem.
Pro nahrazení všech výskytů nějakého řetězce jiným řetežcem lze v php použít například funkci str_replace (popis). Tato funkce vyžaduje alespoň tři parametry:
$radek = str_replace(";","</td><td>",$radek);
Skript upravíme následujícím způsobem:
$pocetradku = 0; while (!feof($soubor)){ $pocetradku = $pocetradku + 1; $radek = fgets($soubor,5000); if ($pocetradku == 1) { print("<h1>".$radek."</h1>"); } else { if ($pocetradku == 2){ print("<table cellspacing=\"0\" cellpadding=\"0\">"); } $radek = str_replace(";","</td><td>",$radek); print("<tr>".$radek."</tr>");0 } } print("</table>");
Podívejme se na vygenerovaný html kód naší stránky a proveďme kontrolu.
Stránka nevypadá jak bychom si představovali. Vídíme, že sloupec jméno je zcela mimo tabulku. Je tedy chyba v html kódu, kterou musíme opravit. Co přesně je v html kódu špatně?
Špatně je, že v každém řádku tabulky chybí v první buňce úvodní tag pro buňku tabulky <td> a stejně tak chybí uzavírací tag pro poslení buňku každého řádku tabulky. Proč tomu tak je? Díky našemu nahrazení jsme sice nahradili všechny středníky pomocí značek pro buňky tabulky, ale uvědomme si, že na začátku ani konci řádku žádný středník nebyl a je tedy nutno tam značky ještě doplnit. Náš skript proto ještě upravíme:
$pocetradku = 0; while (!feof($soubor)){ $pocetradku = $pocetradku + 1; $radek = fgets($soubor,5000); if ($pocetradku == 1) { print("<h1>".$radek."</h1>"); } else { if ($pocetradku == 2){ print("<table cellspacing=\"0\" cellpadding=\"0\">"); } $radek = str_replace(";","</td><td>",$radek); print("<tr><td>".$radek."</td></tr>"); } } print("</table>");
Upravte výsledný skript tak, aby měla tabulka také html hlavičku (označené záhlaví). Nezapomeňte si html kód zkontrolovat pomocí w3 validatoru.
<table width="100%" cellpadding="0" cellspacing="0"> <thead> <tr> <th>Jméno</th><th>Příjmení</th><th>Titul</th><th>E-mail</th><th>Telefon</th><th>Fotografie</th><th>Zkratka</th> </tr> </thead> <tbody> <tr> <td>Radim</td><td>Bárta</td><td>Mgr.</td><td>email</td><td>577007448</td><td>...</td><td>Bár</td> </tr> ... </tbody> </table>
Řešení spočívá v rozšíření existující podmínky pro druhý řádek (hlavička tabulky) a varianty else pro třetí a další řádky.
while (!feof($soubor)){ $pocetradku = $pocetradku + 1; $radek = fgets($soubor,5000); if ($pocetradku == 1) { print("<h1>".$radek."</h1>"); } else { if ($pocetradku == 2){ print("<table cellspacing=\"0\" cellpadding=\"0\">"); $radek = str_replace(";","</th><th>",$radek); print("<thead><tr><th>".$radek."</th></tr></thead>"); print("<tbody>"); }else{ $radek = str_replace(";","</td><td>",$radek); print("<tr><td>".$radek."</td></tr>"); } } }
Výsledný soubor z této lekce si můžete stáhnout: zpracovani-souboru-2.rar
Pokusme se promyslet nedostatky prezentovaného řešení (zejména přemýšlejme nad možnostmi modifikace tabulky, případně nad možnými modifikacemi výstupu).
Pokusme se, s pomocí lekce o tabulkách v html, napsat CSS pravidla pro vzhled tabulky.