Quakenet/#php Tutorial

Hinweis: Wenn sie diese Seite von einer externen URL aufgerufen haben achten sie darauf das alle Kapitel aufeinander aufbauen. Stellen sie daher sicher dass sie alle vorherigen Kapitel gelesen haben, da sie sonst relevante Informationen übersehen.

Fehlermeldungen

  1. Fehler im PHP-Skript
  2. Fehlermeldungen anzeigen lassen
  3. Syntaktische Fehler
  4. Fehlermeldungen verstehen
  5. Semantische Fehler finden

1. Fehler im PHP-Skript

Da niemand Perfekt ist können sich auch Fehler in PHP-Skripten einschleichen. Für den Programmierer heißt dies dass die Fehler im Skript erkannt und beseitigt werden müssen. Dafür stehen dem Programmierer einige Techniken zur Verfügung, von Debugzeilen mit echo über var_dump und debug_print_backtrace bis hin zu Debugger-Möglichkeiten.

2. Fehlermeldungen anzeigen lassen

Um Fehler zu korrigieren müssen diese erstmal gefunden werden. Dies kann daran scheitern dass die entscheidenen Fehlermeldungen nicht angezeigt werden. Je nach PHP-Installation und Konfiguration werden nur bestimmte Typen von Fehlermeldungen angezeigt. Die Wahl der Typen wird durch die Funktion error_reporting bestimmt sowie der dazugehörigen Konfiguration error_reporting in der php.ini. Um alle Typen von Fehlermeldungen zu aktivieren setzt man den Wert für error_reporting auf E_ALL.

<?php
error_reporting
(E_ALL);
?>

Neben dem Wählen der Typen existiert die Einstellung display_errors die angibt ob überhaupt Fehlermeldungen angezeigt werden sollen. Zu Entwicklungszeiten wird diese Einstellung aktiviert, für den laufenden Betrieb wird diese jedoch aus Sicherheitsgründen deaktiviert. In PHP gibt es keine spezielle Funktion um diesen Wert zu aktivieren, daher muss hier die ini_set-Funktion verwendet werden.

<?php
error_reporting
(E_ALL);
ini_set('display_errors'1);
?>

Da nun alle Fehlermeldungen angezeigt werden können nun die entsprechenden Fehler korrigiert werden.

3. Syntaktische Fehler

Syntaktische Fehler sind die einfachsten Fehler in PHP, da sie ein Skript daran hindern überhaupt das PHP-Skript zu starten. Bevor ein PHP-Skript seine Arbeit aufnimmt wandelt der PHP-Interpreter den Quellcode in Tokens um.

<?php
/**
 * Start des Skriptes
 */
$i 10;
do {
    echo 
$i."\n";
    
$i floor($i/2);
} while (
$i)
echo 
'i ist nun '.$i;
?>

Dieses PHP-Skript wandelt PHP in die folgenden Tokens um. Intern behält PHP nur diese Liste, jedoch sind hier die Tokens entsprechend so eingerückt wie sie im Quellcode vorkommen.

T_OPEN_TAG
T_DOC_COMMENT T_WHITESPACE
T_VARIABLE T_WHITESPACE = T_WHITESPACE T_LNUMBER ; T_WHITESPACE
T_DO T_WHITESPACE { T_WHITESPACE
    T_ECHO T_WHITESPACE T_VARIABLE . T_CONSTANT_ENCAPSED_STRING ; T_WHITESPACE
    T_VARIABLE T_WHITESPACE = T_WHITESPACE T_STRING ( T_VARIABLE / T_LNUMBER ) ; T_WHITESPACE
} T_WHITESPACE T_WHILE T_WHITESPACE ( T_VARIABLE ) T_WHITESPACE
T_ECHO T_WHITESPACE T_CONSTANT_ENCAPSED_STRING . T_VARIABLE ; T_WHITESPACE
T_CLOSE_TAG

Zur besseren Übersicht löschen wir alle T_WHITESPACE Tokens, da sie eh ignoriert werden. Sie kommen von den Zeilenumbrüchen und den Leerzeichen im Quellcode.

T_OPEN_TAG
T_DOC_COMMENT
T_VARIABLE = T_LNUMBER ;
T_DO {
    T_ECHO T_VARIABLE . T_CONSTANT_ENCAPSED_STRING ;
    T_VARIABLE = T_STRING ( T_VARIABLE / T_LNUMBER ) ;
} T_WHILE ( T_VARIABLE )
T_ECHO T_CONSTANT_ENCAPSED_STRING . T_VARIABLE ; 
T_CLOSE_TAG

Mit dieser Liste von Tokens kann der PHP-Interpreter nun rechnen. Er prüft nun ob die Tokens an den richtigen Stellen stehen und ob das Zusammenspiel auch passt. Der Ausdruck $i = 10; wird in die Tokenliste T_VARIABLE = T_LNUMBER ; umgewandelt (jetzt ohne T_WHITESPACE). Intern überprüft der PHP-Interpreter ob dies ein gültiger Ausdruck ist, was in diesem Beispiel der Fall ist.

Wenn wir dieses Skript aufrufen werden wir mit folgender Fehlermeldung belohnt.

Parse error: syntax error, unexpected T_ECHO, expecting ';' in DATEI on line 10

Hier ist der PHP-Interpreter nicht mit Zeile 10 zufrieden. Zeile 10 sieht jedoch in Ordnung aus. Das Problem liegt eine Zeile davor, da hinter der do-while-Schleife ein Semikolon vergessen wurde. Der PHP-Interpreter hat sich die Tokens bis dahin angeguckt und gemerkt und erwartet nun nach der schließenden geschweiften Klammer ) ein Semikolon (siehe expecting ';'). Nun, zuerst findet er das T_WHITESPACE Token für den Zeilenumbruch (nicht schlimm, wird ja eh ignoriert). Und dann findet er in Zeile 10 das Token T_ECHO vom echo-Konstrukt. Dies ist absolut nicht erwartet (siehe unexpected T_ECHO) und PHP bricht mit dem Parsen des Skriptes mit einem Parse error ab. Die Liste der erwarteten Tokens ist bei diesen Fehlermeldungen meist gekürzt, da mehrere Tokens folgen können. Alle Token aufzulisten die passen würde keinen weiterbringen. Erstens wissen die Programmierer wie programmiert wird und zweitens ist es wichtig zu Wissen was fehlerhaft ist und nicht was dort vielleicht irgendwie verwendet werden könnte.

Die Zeilenangabe in der Fehlermeldung ist nur die Stelle an der ein Fehler aufgetreten ist, muss aber nicht die Ursache für den Fehler sein. Es gibt dabei so einige Orte wo der Fehler zu suchen ist.

4. Fehlermeldungen verstehen

Neben Syntax Fehlern können auch normale Programmierfehler auftreten, wenn z.B. eine Zahl durch 0 geteilt wird. Der Ausdruck $x = $y / $z; ist zwar syntaktisch richtig, kann aber zu einer Fehlermeldung Warning: Division by zero in DATEI on ZEILE führen. Alle diese Fehlermeldungen besitzen den gleichen Aufbau. Sie beginnen mit einer Klassifizierung der Fehlermeldung. So reicht die Klassifizierung von einem Hinweis (Notice) bis hin zu einem Skriptabbruch (Fatal error). In jedem Fall muss der Programmfehler korrigiert werden. Es reicht nicht das error_reporting-Level runterzuschrauben. Das verhindert zwar die Fehlermeldung, behebt aber nicht den Fehler.

Nach der Klassifizierung kommt die eigentliche Fehlermeldung. Sie beschreibt was passiert ist bzw. was nicht unternommen werden kann. Hier ist die Erfahrung gefragt wie eine Fehlermeldung zu lesen ist. Ein Undefined index '0' mag vielleicht noch einfach zu lesen sein, ein Warning: Cannot modify header information - headers already sent by (output started at DATEI:ZEILE) in DATEI on line ZEILE wohl nicht so einfach, bis hin zu Fehlermeldungen wie Warning: fopen() - No error in DATEI on line ZEILE.

Die angegeben Datei gibt aufschluss wo der Fehler aufgetreten ist, muss aber nicht unbedingt die Quelle der Ursache sein (z.B. wenn eine Variable in einer anderen Datei gesetzt wird). Beliebte Fehler sind auch die falsche Datei zu bearbeiten oder die falsche Datei hochzuladen um dann zu sehen dass der Fehler nach dem Korrigieren doch nicht verschwunden ist.

5. Semantische Fehler finden

Wenn Fehlermeldungen durch PHP angezeigt werden ist es entsprechend einfach den Fehler zu korrigieren. Problematisch sind Fehler die nicht durch PHP erkannt werden, jedoch trotzdem Fehler sind. Diese semantische Fehler können nicht durch PHP erkannt werden, PHP-Skripte arbeiten nur den Plan ab der programmiert wurde.

Um den Verlauf eines PHP-Skriptes zu prüfen muss dieser vorher sauber eingerückt werden. Allein durch das Einrücken können viele logische Fehler bereits erkennt werden, wenn z.B. Programmcode in falschen If-Abfragen liegen. Um des Weiteren z.B. zu prüfen ob eine If-Abfrage betreten wird oder nicht können Debugzeilen eingefügt werden. Dabei handelt es sich um echo- oder var_dump-Aufrufe mit denen der Programmfluss erkannt werden kann.

<?php
echo 'vor der if-abfrage';
if (
bedingung) {
    echo 
'bin in der if-abfrage';
    
mach_was();
} else {
    echo 
'bin im else-teil';
    
mach_dies();
}
echo 
'nach der if-abfrage';
?>

Wenn nun bei diesem PHP-Skript der Text vor der if-abfragebin in der if-abfragenach der if-abfrag ausgegeben wird sieht man einmal dass man wieder einen HTML-Zeilenumbruch <br/> bzw. PHP-Zeilenumbruch \n vergessen hat, aber auch das der PHP-Interpreter den If-Teil der If-Afrage betreten hat. Wenn dies z.B. nicht richtig ist sollten die Bedingungen für die If-Abfragen überprüft werden.

Durch var_dump können dann auch diverse Variablen zum Prüfen der Werte ausgegeben werden.

<?php
while ($i $j) {
    
var_dump($i$j);
    
mach_was_mit($i);
    
mach_dies_mit($j);
    
$i += $j;
}
?>

Dies eignet sich auch um SQL-Querys auszugeben die an MySQL oder andere Datenbanken gesendet werden.

<?php
var_dump
($sql);
mysql_query($sql) or die(mysql_error());
?>

Fragen zum Kapitel

Keine Fragen zum Kapitel vorhanden

Zurück zu Weiter zu
Copyright © bei den OPs von #php.de/QuakeNet Valid XHTML 1.0 Strict Valid CSS!