Diese Rubrik behandelt viele Fehler, die möglicherweise beim Schreiben von PHP-Skripten auftreten.
PHP besteht aus Hunderten externer Bibliotheken, so dass dies manchmal etwas durcheinander erscheint. Eine einfache Regel ist aber wie folgt:
Parameter von Array-Funktionen sind als "needle, haystack" (Nadel, Heuhaufen) geordnet, während die Parameter von String-Funktionen genau andersrum geordnet sind, also als "haystack, needle" (Heuhaufen, Nadel).
PHP bietet viele vordefinierte Variablen, wie das superglobale $_POST. Sie können $_POST mit einer Schleife durchlaufen, da es sich um ein assoziatives Array mit allen über die POST-Methode übertragenen Variablen handelt. Als Beispiel benutzen wir die foreach-Schleife, um (mit der empty()-Funktion) auf leere Werte zu prüfen und geben diese Werte aus.
<?php
$empty = $post = array();
foreach ($_POST as $varname => $varvalue) {
if (empty($varvalue)) {
$empty[$varname] = $varvalue;
} else {
$post[$varname] = $varvalue;
}
}
print "<pre>";
if (empty($empty)) {
print "Keiner der POST-Werte ist leer. Die Werte sind:\n";
var_dump($post);
} else {
print "Wir haben " . count($empty) . " leere Werte:\n";
print "Alle Werte:\n"; var_dump($post);
print "Leer:\n"; var_dump($empty);
exit;
}
?>
Falls Sie dies für eine Datenbank tun möchten, sollten Sie den Maskierungsmechanismus nutzen, der für diese Datenbank vorgesehen ist. Z.B. sollten Sie mysql_real_escape_string() unter MySQL und pg_escape_string() unter PostgreSQL nutzen. Es gibt außerdem die generische Funktionen addslashes() und stripslashes(), die häufig in älterem PHP-Code genutzt werden.
Hinweis: Hinweis zu magic_quotes_gpc
Die PHP-Konfigurationsoption magic_quotes_gpc ist standardmäßig auf on gesetzt. Das bedeutet, dass addslashes() für alle GET-, POST- und COOKIE-Daten automatisch ausgeführt wird. Sie können stripslashes() verwenden, um diese Slashes zu entfernen.
Mit großer Wahrscheinlichkeit existieren die Backslahes, weil die PHP-Direktive magic_quotes_gpc aktiviert ist. Dies ist eine alte Funktionalität von PHP, die nicht mehr aktiviert werden sollte und auf die man sich nicht mehr verlassen sollte. Die PHP-Funktion stripslashes() kann genutzt werden, um die Backslashes aus dem string zu entfernen.
Hinweis: Hinweis zu magic_quotes_gpc
Die PHP-Konfigurationsoption magic_quotes_gpc ist standardmäßig auf on gesetzt. Das bedeutet, dass addslashes() für alle GET-, POST- und COOKIE-Daten automatisch ausgeführt wird. Sie können stripslashes() verwenden, um diese Slashes zu entfernen.
Dieses Feature ist seit PHP 5.3.0 DEPRECATED (veraltet) und seit PHP 5.4.0 ENTFERNT.
Zunächst eine Erklärung zu dieser INI-Einstellung. Angenommen, Sie benutzen den folgenden URL: http://example.com/foo.php?animal=cat und Sie haben in foo.php den folgenden PHP-Code:
<?php
// die Benutzung von $_GET wird empfohlen
echo $_GET['animal'];
// damit $animal existiert, muss register_globals eingeschaltet sein
// NICHT EMPFOHLEN
echo $animal;
// dies gilt für alle Variablen, also auch für $_SERVER
echo $_SERVER['PHP_SELF'];
// damit $PHP_SELF existierst, muss register_globals eingeschaltet sein
// NICHT EMPFOHLEN
echo $PHP_SELF;
?>
Der obige Code zeigt, dass register_globals eine große Zahl von Variablen erzeugt. Diese Art der Programmierung wird seit vielen Jahren nicht mehr empfohlen und wurde deswegen standardmäßig deaktiviert. Obwohl auf den meisten Servern register_globals deaktiviert ist, existieren immer noch alte Artikel, Tutorials und Bücher, die davon ausgehen, dass dieses Feature aktiviert ist.
Weitere Informationen finden Sie auf den folgenden Seiten:
Hinweis:
Im obigen Beispiel wird ein URL benutzt, der einen QUERY_STRING enthält. Solche Informationen werden über einen GET-HTTP-Request übergeben, weswegen das Superglobal $_GET benutzt wird.
<?php
function myfunc($argument)
{
echo $argument + 10;
}
$variable = 10;
echo "myfunc($variable) = " . myfunc($variable);
?>
Um das Ergebnis Ihrer Funktion in einem Ausdruck verwenden zu können (um es z.B. wie im obigen Beispiel mit dem anderen String zu verbinden), müssen Sie den Wert mit return zurückgeben und ihn nicht mit echo ausgeben.
<pre>
<?php echo "Das soll die erste Zeile sein."; ?>
<?php echo "Das soll nach dem obigen Zeilenumbruch erscheinen."; ?>
</pre>
In PHP können Code-Blöcke entweder mit "?>" oder mit "?>\n" enden (\n steht für Zeilenumbruch). Im obigen Beispiel sind die ausgegebenen Zeilen daher in einer Zeile, denn PHP lässt die Zeilenumbrüche nach den Block-Ende-Zeichen weg. Wenn Sie möchten, dass PHP einen Zeilenumbruch ausgibt, müssen Sie nach jedem Code-Block einen zusätzlichen Zeilenumbruch einfügen.
Warum macht PHP das so? Wenn Sie normales HTML formatieren, erleichert PHP Ihnen die Arbeit, da Sie meist diesen Zeilenumbruch gar nicht haben möchten. Würde PHP diesen Zeilenumbruch ausgeben, müssten Sie sehr lange Zeilen schreiben und Ihren Code damit unlesbar machen.
Die Funktionen header(), setcookie() und die Session-Funktionen müssen Header dem Output-Stream hinzufügen. Header können aber nur gesendet werden, wenn Sie vor allen anderen Daten gesendet werden. Vor dem Aufruf dieser Funktionen darf also keine Ausgabe (wie z.B. HTML-Code) stattfinden. Die Funktion headers_sent() prüft, ob Ihr Skript bereits Header gesendet hat. Nützlich sind in diesem Zusammenhang auch die Funktionen zur Ausgabesteuerung.
Wenn Sie PHP als Apache-Modul laufen lassen, liefert Ihnen die getallheaders()-Funktion die gewünschten Informationen. Der folgende Code gibt alle Request-Header aus:
<?php
$headers = getallheaders();
foreach ($headers as $name => $content) {
echo "headers[$name] = $content<br />\n";
}
?>
Siehe auch apache_lookup_uri(), apache_response_headers() und fsockopen().
Das Sicherheitsmodell des IIS hat Unrecht. Dies ist ein Problem, das alle CGI-Programme, die unter dem IIS laufen, haben. Als Workaround können Sie eine leere HTML-Datei, die nicht von PHP geparst wird, als Eingangsseite in ein per Authenfikation geschütztes Verzeichnis erzeugen. Anschließend leiten Sie den Browser durch ein META-Tag auf die PHP-Seite weiter oder sie setzen einen Link auf die PHP-Seite. PHP erkennt dann die Authentifizierung korrekt. Dieses Problem tritt mit dem ISAPI-Modul nicht auf. Auch auf anderen NT-Web-Servern sollte dieses Problem nicht auftauchen. Weitere Informationen finden Sie auch hier: » http://support.microsoft.com/kb/q160422/. Lesen Sie auch den Manual-Abschnitt zur HTTP-Authentifizierung mit PHP.
Sie müssen die Go to Internet Information Services ändern. Suchen Sie Ihre PHP-Datei und rufen Sie deren Eigenschaften auf. Wechseln Sie auf das Register File Security, klicken Sie dort auf Edit -< Anonymous access and authentication control.
Sie können das Problem beheben, indem Sie entweder den Haken bei Anonymous Access entfernen und ihn bei Integrated Window Authentication belassen, oder indem Sie Anonymous Access ankreuzen und dann die Berechtigungen der Benutzer, die keinen Zugriff bekommen sollen, anpassen.
Um <?xml in Ihren PHP-Code einzufügen müssen Sie die Kurzform der öffnenden PHP-Tags abschalten, indem Sie in Ihrer php.ini short_tags auf 0 setzen. Sie können diese Direktive nicht mit der Funktion ini_set() setzen. Sie können unabhängig davon, ob short_open_tags aktiviert oder deaktiviert ist, z.B. <?php echo '<?xml'; ?> benutzen. Der Standardwert für diese Direktive ist On.
Lesen Sie die Manual-Seite zu vordefinierten Variablen, die eine (unvollständige) Liste der vordefinierten Variablen, die Ihren Skripten zur Verfügung stehen, enthält. Eine komplette Liste der verfügbaren Variablen (und viele weitere Informationen) können Sie sehen, wenn Sie die Funktion phpinfo() aufrufen. Beachten Sie auch den Abschnitt zu Variablen außerhalb von PHP, der verschiedene Szenarien für externen Variablen wie HTML-Formulare, Cookies oder den URL beschreibt.
Hinweis: register_globals: Wichtiger Hinweis
Seit PHP 4.2.0 ist die Standardeinstellung für die Konfigurationsoption register_globals off. Die PHP-Community ermutigt alle, sich nicht auf diese Option zu verlassen und Alternativen wie superglobals zu verwenden.
Es gibt einige in PHP geschriebene Alternativen wie » FPDF und » TCPDF.
Des Weiteren gibt es die Haru-Erweiterung, die die freie libHaru-Bibliothek benutzt.
Es ist wichtig, zu verstehen, dass die PHP-Direktive register_globals auch Server- und Umgebungsvariablen betrifft. Wenn register_globals = off (Standardwert seit PHP 4.2.0), dann existiert $DOCUMENT_ROOT nicht. Stattdessen können Sie $_SERVER['DOCUMENT_ROOT'] benutzen. Wenn register_globals = on, dann existieren auch die Variablen $DOCUMENT_ROOT und $GLOBALS['DOCUMENT_ROOT'].
Wenn Sie sicher sind, dass register_globals = on, und sich wundern, warum $DOCUMENT_ROOT innerhalb von Funktionen nicht verfügbar ist: das liegt daran, dass es sich dabei um eine Variable wie jede andere handelt und sie deswegen innerhalb der Funktion zunächst global $DOCUMENT_ROOT benutzen müssen. Siehe auch die Manual-Seite zum Geltungsbereich von Variablen. Empfehlenswert ist, register_globals = off zu verwenden.
Die verfügbaren Abkürzungen sind K (für Kilobytes), M (für Megabytes) und G (für Gigabytes, verfügbar seit PHP 5.1.0), Groß-/Kleinschreibung spielt dabei keine Rolle. Alle anderen Werte werden als Byte-Werte erkannt. 1M entspricht z.B. einem Megabyte oder 1048576 Bytes. 1K entspricht einem Kilobyte oder 1024 Bytes. Sie können diese abgekürzten Schreibweise nicht außerhalb der php.ini verwenden. Vergleiche auch die Dokumentation von ini_get() für ein Beispiel, wie diese Werte konvertiert werden.
Hinweis: Kilobyte versus Kibibyte
Die PHP-Notation beschreibt ein Kilobyte als Entsprechung von 1024 Bytes, während der IEC-Standard dies als Kibibyte bezeichnet. Zusammenfassung: k und K = 1024 Bytes.
Vor PHP 5.3.4 gab es einen Bug im Netzwerk-Auflösungs-Code von PHP, der dazu führte, dass localhost im Zusammenhang mit Streams fehlschlug, wenn IPv6 aktiviert war. Um dieses Problem zu umgehen, können Sie entweder "127.0.0.1" verwenden oder die Auflösung von IPv6 in der hosts-Datei deaktivieren.