Anglická verze
logolink

< Zpět na seznam lekcí

Zpracování a úprava textového souboru v PHP

PHPObsah lekce:

  • Popis skriptu pro přepis souboru do prohlížeče
  • Popis nedostatků ve výstupu
  • Řešení nedostatků ve výstupu
  • Zpracování dat v řádku do tabulky

Výsledná podoba skriptu na přepis souboru do prohlížeče

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.

Současná podoba skriptu
          <!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>
          

Cvičení

Pokusme se podrobně popsat jednotlivé řádky souboru, jejich význam a funkci.

Popis nedostatků ve výstupu

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

zobrazeni obsahu souboru v prohlížeči

Pokusme se popsat vše, co je potřeba v současném výstupu napravit, abychom dosáhli našeho cíle.

  1. Upravit nadpis - odstranit středníky z řádku s nadpisem a také z řádku následujícího. Nadpis je nutno také správně označkovat html tagy.
  2. Z dat v souboru vytvořit html tabulku - korektně vložit html značky pro začátek a konec tabulky a správně označkovat řádky a sloupce tabulky.
  3. Vhodně rozdělit data v řádku na jednotlivé položky (možnost manipulace s jednotlivými sloupci a odstranění středníků ve výstupu).

Úprava nadpisu a druhého řádku

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

Zpracování prvního řádku jako nadpisu
	$pocetradku = 0;
	while (!feof($soubor)){
		$pocetradku = $pocetradku + 1;
		$radek = fgets($soubor,5000);
		if ($pocetradku == 1) {
			print("<h1>".$radek."</h1>");
		} else {
			print($radek);
			print("<br />");
		}
	}
          

Vložení html značek pro tabulku

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.

Vložení html značek pro začátek a konec tabulky
	$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.

HTML kód produkovaný našim skriptem
<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.

Vložení html značek pro začátek a konec tabulky
	$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.

Zpracování dat v řádku

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.

Řešení 1 - prosté nahrazení

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

Cvičení

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.

Funkce str_replace v PHP

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:

  • hledaný řetězec - reprezntuje posloupnost znaků, kterou hledám. V našem případě jde o znak středník (ten hledám, ten chci nahradit).
  • náhrada - toto je řetězec, kterým chceme každý výskyt hledaného řetězce nahradit. V našem případě se jedná o řetězec </td><td>.
  • vstupní řetězec - jako třetí parametr udáváme řetězec, ve kterém chceme nahradit všechny výskyty hledaného řetězce náhradou. Tímto řetězcem je pro nás řetězec v proměnné $radek.
Použití funkce str_replace
$radek = str_replace(";","</td><td>",$radek);

Skript upravíme následujícím způsobem:

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

vystup a html kód

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:

Skript
	$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>");
  			

Cvičení

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.

HTML kód tabulky s hlavičkou
<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í

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

Řešení cvičení - doplnění značek pro hlavičku tabulky
	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

Domácí úkol

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.

Další čtení

Odkazy

Otázky

  1. Vysvětlete funkcionalitu výsledného skriptu z této lekce.
  2. Vysvětlete práci funkce str_replace a ukažte její použití na příkladu.
  3. Pokuste se nalézt další funkce pro práci s řetězci v PHP.
webdesign, xhtml, css, php - Mgr. Michal Mikláš