Konsten att felsöka PHP
Förord
Allt för många frågor i forum skulle kunna lösas genom lite enkel felsökning. Jag kommer visa några varianter för att slippa riva håret i onödan.När du programmerar ägnas mycket tid till att felsöka koden, mycket onödig tid. Allt eftersom blir du mer och mer van vid att felsöka koden och du kommer lättare att hitta felen. Jag kommer därför att visa några förslag på hur du felsöker på ett bra sätt. Men felsökning är som sagt en konst, därför finns det många olika varianter.
Det finns olika typer av felmeddelanden i PHP.
Bland annat webbläsaren Internet Explorer har som standard-inställning att inte visa felmeddelanden från t.ex. PHP eller ASP om de inte har en teckenmängd som är större än ~500 tecken.
Gå därför in i avancerade inställningar i webbläsaren (Internet Explorer) Verktyg > Internetinställningar > Avancerat. Leta sedan upp raden med "Visa egna HTTP-felmeddelanden" och se till att den inte är förbockad.
Kontrollera även om din felrapportering är på, börja med detta om du inte får något felmeddelande över huvud taget
Detta kommer att göra så att alla felmeddelanden kommer att rapporteras.
Vill du även att din webbserver (i detta fallet Apache) ska lagra felmeddelandena i en separat fil kan du ange detta i php.ini:
Utan tvekan det vanligaste felmeddelandet som dyker upp. Det beror på att något bryter mot PHP's syntax. Det resulterar oftast i ett 'Parse error'-felmeddelande från PHP.
Kod:
Följande felmeddelande kommer att dyka upp:
Parse error: parse error, unexpected T_VARIABLE in /1.php on line 5
Du bryter således mot syntaxen då du glömmer bort semikolonet på rad 4 och sedan börjar skapa en variabel igen på rad 5. PHP har ännu inte avslutat variabeltilldelningen på rad 4 och blir förvirrat.
Syntax error är vanligt förekommande i stora block av if-else eller while där det är lätt att glömma bort en hakparantes eller parantes.
'Semantic errors' uppstår när du skriver kod som följer syntaxen men som bryter mot PHP's "körningsregler".
'Semantic errors' resulterar oftast i ett 'Warning'-felmeddelande från PHP.
Kod:
PHP kommer redan på rad 2 att kasta ur sig ett felmeddelande om inte 'config.php' existerar.
Warning: main(config.php) [function.main]: failed to open stream: No such file or directory in /2.php on line 2
'Enviroment errors' uppstår när något externt system till ett PHP-script orsakar ett problem. T.ex, om du försöker ansluta till en MySQL-server som inte är tillgänglig eller försöker öppna
Dessa felmeddelanden är ofta bortom programmerarens kontroll. De kan även uppstå i PHP när t.ex. register_globals är avstängt.
'Logic errors' är de svåraste felen att hitta. Scriptet körs perfekt och inga felmeddelanden dyker upp, men scriptet gör inte rätt saker! Det gör saker i fel ordning osv.
Något som du bör ha i åtanke när du utvecklar script för affärskritiska system, är att du testar koden på din lokala server först. Därför att då dyker inte dessa logiska fel upp på ditt affärskritiska system om du testat det ordentligt på din lokala server.
Detta är en av PHP's starka sidor i och med att du kan skriva koden på ena systemet och sedan bara flytta över koden, detta kallas portabel kod. Så länge det är samma programvaror spelar det i stort sett inte någon roll vilket operativsystem det körs på.
Om du, trots dina försök att hitta felet, inte lyckas så är det en bra idè att bryta ner koden i mindre delar och kontrollera varje värde för sig.
Ofta beror felmeddelandena på att ett värde har på något sätt blivit tomt. Därför är det en bra idè att plocka isär värdena var för sig och sedan skriva ut dem för att kontrollera dem.
Exempel - Kontrollera om värdena från din $_POST innehåller rätt värden.
När du felsöker en SQL-fråga är det ofta bra att skriva ut SQL-frågan för sig och kontrollera värdena.
Exempel: Kontrollera om värdena i SQL-frågan finns
Då bör du se om den innehåller värdena du vill.
Med de flesta felmeddelandena följer oftast ett radnummer. I många fall så är det inte på denna rad felet ligger utan några rader upp. Det kan vara att du glömt ett semikolon (;) eller en parantes för mycket/lite.
Ofta händer det att felmeddelandet pekar mot en rad som inte existerar, detta beror nästan jämt på att du glömt en hakparantes ( } ) som avslutar ditt block.
Det kan uppstå situationer då din kod inte ens körs. För att få reda på hur långt koden kommer innan den avslutas eller skickas om till en annan del i koden, kan du använda dig av die();
Om du då anser att värdet $_POST['var'] är tomt så bör då koden skriva ut Koden körs här. Om du då märker att koden skriver ut Koden körs i elsen. Så kan du börja felsöka variabeln $_POST['var'].
Om du får ett felmeddelande utan en hänvisning till ett radnummer så kan du även här använda dig av samma metod som du använde dig av i 2.3 och pröva dig fram genom att sätta in die(); på lämpliga ställen.
Förhoppningsvis så har du lärt dig några olika varianter för att felsöka lättare. Jag säger absolut inte att mina sätt är bättre än någon annans men jag tycker att de fungerar rätt bra för mig i alla fall.
1. Vad betyder felmeddelandena?
Det finns olika typer av felmeddelanden i PHP.
1.1 Visa felmeddelandena
Bland annat webbläsaren Internet Explorer har som standard-inställning att inte visa felmeddelanden från t.ex. PHP eller ASP om de inte har en teckenmängd som är större än ~500 tecken.Gå därför in i avancerade inställningar i webbläsaren (Internet Explorer) Verktyg > Internetinställningar > Avancerat. Leta sedan upp raden med "Visa egna HTTP-felmeddelanden" och se till att den inte är förbockad.
Kontrollera även om din felrapportering är på, börja med detta om du inte får något felmeddelande över huvud taget
error_reporting(E_ALL);
?>
Detta kommer att göra så att alla felmeddelanden kommer att rapporteras.
Vill du även att din webbserver (i detta fallet Apache) ska lagra felmeddelandena i en separat fil kan du ange detta i php.ini:
php_value error_log /fullständig sökväg till katalogen/error_log
1.2 Syntax error
Utan tvekan det vanligaste felmeddelandet som dyker upp. Det beror på att något bryter mot PHP's syntax. Det resulterar oftast i ett 'Parse error'-felmeddelande från PHP.Kod:
$msg = '';
$msg .= 'Detta är';
$msg .= 'ett meddelande som'
$msg .= 'sträcker sig över flera rader';
?>
Följande felmeddelande kommer att dyka upp:
Du bryter således mot syntaxen då du glömmer bort semikolonet på rad 4 och sedan börjar skapa en variabel igen på rad 5. PHP har ännu inte avslutat variabeltilldelningen på rad 4 och blir förvirrat.
Syntax error är vanligt förekommande i stora block av if-else eller while där det är lätt att glömma bort en hakparantes eller parantes.
1.3 Semantic errors
'Semantic errors' uppstår när du skriver kod som följer syntaxen men som bryter mot PHP's "körningsregler". 'Semantic errors' resulterar oftast i ett 'Warning'-felmeddelande från PHP.
Kod:
include('config.php');
// use variable from 'config.php'
$inc_var = 'foo';
?>
PHP kommer redan på rad 2 att kasta ur sig ett felmeddelande om inte 'config.php' existerar.
1.4 Enviroment errors
'Enviroment errors' uppstår när något externt system till ett PHP-script orsakar ett problem. T.ex, om du försöker ansluta till en MySQL-server som inte är tillgänglig eller försöker öppnaDessa felmeddelanden är ofta bortom programmerarens kontroll. De kan även uppstå i PHP när t.ex. register_globals är avstängt.
1.5 Logic errors
'Logic errors' är de svåraste felen att hitta. Scriptet körs perfekt och inga felmeddelanden dyker upp, men scriptet gör inte rätt saker! Det gör saker i fel ordning osv.Något som du bör ha i åtanke när du utvecklar script för affärskritiska system, är att du testar koden på din lokala server först. Därför att då dyker inte dessa logiska fel upp på ditt affärskritiska system om du testat det ordentligt på din lokala server.
Detta är en av PHP's starka sidor i och med att du kan skriva koden på ena systemet och sedan bara flytta över koden, detta kallas portabel kod. Så länge det är samma programvaror spelar det i stort sett inte någon roll vilket operativsystem det körs på.
2. Bryt ner koden
Om du, trots dina försök att hitta felet, inte lyckas så är det en bra idè att bryta ner koden i mindre delar och kontrollera varje värde för sig.
2.1 Kontrollera värderna
Ofta beror felmeddelandena på att ett värde har på något sätt blivit tomt. Därför är det en bra idè att plocka isär värdena var för sig och sedan skriva ut dem för att kontrollera dem.Exempel - Kontrollera om värdena från din $_POST innehåller rätt värden.
echo "";
print_r($_POST);
echo "
";
?>
När du felsöker en SQL-fråga är det ofta bra att skriva ut SQL-frågan för sig och kontrollera värdena.
Exempel: Kontrollera om värdena i SQL-frågan finns
$sql = "SELECT id,subject FROM table_users WHERE uid = ".$uid."
AND fid = ".$fid;
echo "SQL:
";
die($sql);
?>
Då bör du se om den innehåller värdena du vill.
2.2 Var är det fel?
Med de flesta felmeddelandena följer oftast ett radnummer. I många fall så är det inte på denna rad felet ligger utan några rader upp. Det kan vara att du glömt ett semikolon (;) eller en parantes för mycket/lite.Ofta händer det att felmeddelandet pekar mot en rad som inte existerar, detta beror nästan jämt på att du glömt en hakparantes ( } ) som avslutar ditt block.
2.3 Körs koden?
Det kan uppstå situationer då din kod inte ens körs. För att få reda på hur långt koden kommer innan den avslutas eller skickas om till en annan del i koden, kan du använda dig av die(); if (empty($_POST['var']))
{
$var = NULL;
die("Koden körs här");
}
else
{
$foo = $bar;
die("Koden körs i elsen");
}
?>
Om du då anser att värdet $_POST['var'] är tomt så bör då koden skriva ut Koden körs här. Om du då märker att koden skriver ut Koden körs i elsen. Så kan du börja felsöka variabeln $_POST['var'].
2.4 Fel utan radnummer
Om du får ett felmeddelande utan en hänvisning till ett radnummer så kan du även här använda dig av samma metod som du använde dig av i 2.3 och pröva dig fram genom att sätta in die(); på lämpliga ställen. 3. Summering
Förhoppningsvis så har du lärt dig några olika varianter för att felsöka lättare. Jag säger absolut inte att mina sätt är bättre än någon annans men jag tycker att de fungerar rätt bra för mig i alla fall.
Mathias Olsson
Det är ju roligast om man kan lösa sina problem själv. Fler sådana här tips, tack. För min egen del var det inte så mycket nyheter, men jag är övertygad om att om alla nybörjare läste arikeln, skulle många enkla problem inte behöva ta upp plats i forumen :) "print_r($_POST)" är en mycket bra grej som jag inte har tänkt på. Tack!