Základní kurz 5: Hledání a oprava chyb ve skriptu

Autor: Joker
V minulé části učebnice jsme si ukázali první PHP příkazy a první skutečné PHP skripty. Pokud jste experimentovali s vlastním kódem, možná se už někdy místo očekávaného výstupu na stránce objevilo chybové hlášení.
zkuste například tento kód:
<?php
echo "Tohle nebude fungovat

?>

Uložte do kořene webu třeba jako priklad_chyba.php a zkuste stránku zobrazit (http://localhost/priklad_chyba.php). Mohou nastat dvě možnosti: Buď se nezobrazí vůbec nic, jen čistá prázdná stránka, nebo se zobrazí zhruba toto:
Parse error: syntax error, unexpected $end in C:\www\priklad_chyba.php on line 4

Jak se k chybové hlášce dostat?


Nejjednodušší je situace, kdy se hláška zobrazí přímo do stránky, nebo místo stránky. Kromě toho se mohou hlášky zapisovat do logu (případně zároveň do stránky a do logu), nebo se nemusejí vypisovat vůbec, v tom případě se k nim samozřejmě nedostanete. Toto se řídí třemi nastaveními, která najdete v konfiguračním souboru PHP Jak najít konfigurační soubor?

První je error_reporting. To určuje, které chyby se budou zobrazovat. Hodnota nastavení by měla být E_ALL (od PHP 5.4 zaznamenává i úroveň Strict standards, ve starších verzích ne), nebo E_ALL | E_STRICT (zaznamená všechna upozornění včetně Strict standards i ve starších verzích). Nastavení error_reporting se zobrazuje i ve výpisu phpinfo, kde se ale zobrazí jako číslo, navíc číslo odpovídající nastavení E_ALL se v různých verzích PHP může lišit. V PHP 5.3 hodnotě E_ALL odpovídá 30719 a hodnotě E_ALL | E_STRICT odpovídá 32767.

Dále jsou důležitá ještě nastavení display_errors a log_errors. U obou může být nastavení On (zapnuto) a Off (vypnuto).
Nastavení display_errors = On zapne zobrazování chyb do stránky. Toto je vhodné pro vývojový server, kde stránky zobrazuje zároveň programátor skriptu a je tak hned upozorněn na chyby.
Nastavení display_errors = Off je naopak vhodné pro zveřejněný web. Tam hlášku vypsanou do stránky místo autora kódu uvidí nějaký běžný návštěvník, který obvykle nepochopí o co jde, nepředá informaci o chybě správci webu a nikdo to po něm ani nemůže žádat. V nejhorším případě by informace z chybové hlášky dokonce mohl zneužít, například web hacknout.

Nastavení log_errors = On zapíše hlášku do chybového logu.
Toto je vhodné pro konečné zveřejněné stránky, kdy návštěvníci chyby neuvidí a zároveň správce má šanci se o nich dovědět. Pro informace, jak se k chybovému logu dostat, kontaktujte poskytovatele hostingu daného webu.

Existuje také rozšíření do PHP zvané XDebug, se kterým jsou vypisované hlášky barevnější a obsahují více informací.

Ta podstatná věc ale stále je text chybové hlášky.

Když už máte chybovou hlášku, co s ní?

Hodně začátečníků při pohledu na takovou hlášku napadne jedna ze dvou věcí:
1) Jak takové hlášky vypnout, aby se nezobrazovaly?
2) Řeknou si, že něco je špatně, otevřou v lepším případě diskusi o PHP (v horším diskusi o něčem úplně jiném) a v lepším případě napíší kód, chybovou hlášku a prosbu o radu (v horším napíší něco jako „Napsal jsem kód a nefunguje mi. Poraďte a fofrem.“ A milí diskutující aby pro zjištění problému ovládali minimálně telepatii)

Obojí je špatně, to první je víc špatně, to druhé méně špatně.
V první řadě si pamatujte: Chybové hlášky jsou naši přátelé, upozorňují na problémy ve skriptu. Reagovat na chybové hlášky vypnutím jejich zobrazování je podobné jako „vyřešit“ špatné výsledky zdravotní prohlídky tím, že přestanete chodit k lékaři.
Takže: Nepotlačujeme chybové hlášky, ale řešíme problém, který je jejich příčinou. Samy o sobě jsou chybové hlášky dobré, nejhorší co může programátor řešit je, když kód nefunguje správně a nejsou žádné indicie k tomu proč.

Ke druhému bodu, vždy byste se měli alespoň pokusit vyřešit chybu sami. To nejmenší co můžete udělat je vložit text chybové hlášky do vyhledávače. Dotaz na diskusi by měl vždycky být až další možnost poté, co selhal pokus vyřešit problém samostatně.

Oba body narážejí na častý problém začátečníků:

Co ty chybové hlášky znamenají?


Chybové hlášky jsou v angličtině, pro hodně lidí vypadají minimálně na první pohled nesrozumitelně a nepochopitelně. Když se na ně ale podíváte blíže, mají chybové hlášky podobnou strukturu a i bez znalosti angličtiny z nich můžete vyčíst základní informace. Tak jako v celém programování ale platí, že alespoň základní znalost angličtiny velmi usnadní práci.
Parse error: syntax error, unexpected $end in C:\www\priklad_chyba.php on line 4

Hláška se dělí na několik částí:
1. Typ chyby (Parse error)
2. Upřesnění chyby (syntax error, unexpected $end)
3. Cesta k souboru, kde byla chyba zjištěna (C:\www\priklad_chyba.php)
4. Na kterém řádku byla chyba zjištěna (na 4. řádku)

Podívejme se na jednotlivé části blíže:

1. Typ chyby.


Může to být jeden z následujících:

Parse error (chyba zpracování skriptu)

Znamená, že daný skript není platný PHP kód. Jako začátečníci se s touto chybou budete setkávat asi nejčastěji. Přitom zejména tyto chyby byste se měli snažit vyřešit sami, protože to většinou bývají banální chyby typu zapomenutý středník či uvozovka (jako i v našem příkladu). V hledání těchto chyb pomůže i zvýrazňovač syntaxe v IDE.

Fatal error (fatální chyba)

Ve skriptu nastala tak zásadní chyba, že nelze pokračovat v jeho zpracování.
Vypíše se chybová hláška a skript je ukončen. Fatální chybu může generovat třeba pokus o vložení neexistujícího souboru do stránky pomocí příkazu require.

Warning (varování)

Ve skriptu nastala chyba, ale je možné pokračovat ve zpracování. Vypíše se chybová hláška a zpracování skriptu pokračuje. Varování může generovat třeba pokus o vložení neexistujícího souboru do stránky pomocí příkazu include (který se od require liší právě úrovní chyby v případě neexistence souboru), nebo volání funkce se špatnými argumenty.

Notice (poznámka)

Ve skriptu nastala situace, která bývá projevem chyby, ale může k ní dojít i při normálním běhu. Vypíše se chybová hláška (resp. poznámka) a skript pokračuje ve zpracování.
Poznámky může občas generovat i kód, který jinak funguje správně. I tak je ale dobré se jim věnovat a nechat je bez opravy jen pokud k tomu existuje pádný důvod.

Deprecated

Skript používá funkčnost, která je v PHP označena jako deprecated (někdy se překládá „zavržená“, význam je zastaralá, překonaná), což znamená, že daná funkčnost je zastaralá nebo nějakým způsobem problematická, není už podporovaná a do budoucna může být odstraněna.
Toto není chyba a skript bude s danou verzí PHP fungovat, ale při přechodu na novější verzi PHP by fungovat nemusel.
Funkčnost označená jako deprecated je obvykle nahrazena nějakou novější, zjistěte si jakou a při psaní nových skriptů používejte tu novější. U starých skriptů aktualizujte příležitostně až tam budete něco měnit, nebo pokud plánujete přechod na novější verzi PHP.

Strict standards

Upozornění na prohřešky proti „dobrým způsobům“ při psaní PHP skriptů.
Nejde přímo o chybu a může se objevit i u kódu, který funguje správně, ale šel by napsat "lépe".
Upozornění typu Strict standards bývají často vypnutá dokonce i na serverech, které jinak všechny ostatní hlášky vypisují.

Shrnutí k typům chyb

Přehled výše je zhruba sestupně podle závažnosti chyby.
Hlášení typu Parse error (chyba zpracování skriptu), Fatal error (fatální chyba) a Warning (varování) upozorňují na závažné problémy a skript je nutné opravit.
Hlášení typu Notice (poznámka) znamenají problémy, které často neznamenají akutní problém a skript funguje, nebo se zdá, že funguje. Ovšem právě situace, kdy skript zdánlivě funguje, ale ve skutečnosti v něm je problém, jsou velmi nebezpečné, takže i tuto úroveň je vhodné prověřit.
Hlášení typu Deprecated a Strict standards obvykle neznamenají přímo chyby, ale potenciální problémy ohledně kompatibility a interoperability (spolupráce s jinými skripty). U nově tvořených skriptů je vhodné se jimi zabývat hned, u starších skriptů stačí při příští úpravě či údržbě kódu.

2. Popis chyby


Text chybové hlášky. Tady už se bez angličtiny obvykle neobejdete, ale texty hlášek nebývají komplikované a pokud jim přesto nerozumíte, můžete použít nějaký automatický překladač.
V naší ukázce je text hlášky "syntax error, unexpected $end", tedy: Chyba syntaxe, neočekávaný (neočekáváno) $end. Takhle vypadá většina chyb způsobených špatným zápisem skriptu: Chyba syntaxe, neočekávané něco. V našem případě je to $end, konec skriptu.
Neočekávaný konec skriptu obvykle znamená, že jsme zapomněli na ukončení něčeho co musí být ukončeno, v našem případě na ukončení řetězce.

3. Cesta k souboru, kde byla chyba zjištěna


V tomto souboru byste měli po chybě začít pátrat. Je udána fyzická cesta k souboru na disku, ne webová adresa.

4. Na kterém řádku byla chyba zjištěna


Konkrétní místo v souboru, kde začít pátrat. Tady vidíme, proč jedním z požadavků na PHP editor bylo, aby uměl zobrazit čísla řádků.
Zde je třeba upozornit na jednu komplikaci: soubor a číslo řádku označuje místo, kde byla chyba zjištěna, nikoli místo, které je skutečně příčinou chyby.
Můžeme to vidět i na naší ukázce: Skutečná příčina chyby je zapomenutá uvozovka na druhém řádku, ale PHP nemůže vědět, co autor chtěl napsat a řídí se jen pravidly PHP syntaxe. Odřádkování uvnitř řetězce být může, takže chyba je zjištěna až při porušení pravidel syntaxe PHP, tedy na řádku 4, kde skript skončí bez ukončení řetězce (proto je také chybová hláška neočekávaný konec skriptu). Skutečný problém ve skriptu tedy může být na řádku uvedeném v chybové hlášce, ale často bývá dříve ve skriptu.

Vyzkoušejte si

1. Pokud jste při zkoušení příkladů z minulé kapitoly dostali chybovou hlášku (nebo prázdnou stránku), zkuste se k nim nyní vrátit a chybu najít a opravit.

2. Zkuste si uložit a spustit z minulé kapitoly z části „Ohraničení PHP skriptu“ skript ukazující, že uvnitř PHP nemůže být HTML kód (poznámka: Tento skript je syntakticky chybně a má tedy skončit chybovou hláškou).
Sledujte, jak editor a zvýrazňovač syntaxe reaguje na místa, která neodpovídají syntaxi PHP.
V prohlížeči se podívejte na výstup skriptu, jakou chybu na jakém řádku PHP nahlásí.

3. Zkuste napsat skript se dvěma příkazy include, kdy prvním se pokusíte vložit soubor který neexistuje a druhým nějaký existující soubor (třeba k4_paticka.php z minulé kapitoly). Podívejte se, jakou chybovou hlášku PHP vypíše. Pak v témže skriptu příkaz include nahraďte příkazem require a opět se podívejte na výstup skriptu.
Poznámka: Text chybové hlášky by měl být "failed to open stream: No such file or directory". Dostanete-li jinou, máte nejspíše ve skriptu syntaktickou chybu. Opravte skript, abyste se dostali k uvedené chybové hlášce.

Máte návrh na vylepšení či doplnění článku? Obsahuje článek nepřesné informace, nebo v něm chybí něco důležitého?
Tento článek má diskusní vlákno na diskusi Jak Psát Web, kam můžete náměty a připomínky napsat.

Správcem webu Péhápko.cz je Joker, mail zavináč it-joker tečka cz. Informace o autorských právech a možnostech použití obsahu viz Autorská práva
Přihlášení