Um die Kompatibilität zwischen PHP-Versionen zu maximieren und die Sicherheit und die Wartbarkeit von PHP-Skripten zu gewährleisten sollte sichergestellt sein, dass folgende Regeln eingehalten werden:
Auch wenn PHP sehr dynamisch ist, ist das Deklarieren von Variablen nicht unwichtig. Denn im Funktionskopf deklarierte Variablen verschaffen einen Überblick und Komplexität des Algorithmus und geben den sehr wichtigen Hinweis auf den Typ einer Variable.
function meine_funktion($param) { $s = 0; // Zählvariable $ret = ""; // Rückgabe for ($s; $s < 10; $s++) $ret .= $s; return $ret; }
function meine_funktion($param) { for ($s = 0; $s < 10; $s++) $ret .= $s; return $ret; }
Da PHP keine Typisierung unterstützt, liegt es in der Verantwortung des Programmierer diese zu gewährleisten. Vorallem Eingabewerte sollten strikt typisiert werden. Dies ist auch sinnvoll um SQL-Injections zu vermeiden.
$id = intval($_GET["id"]);
$id = $_GET["id"];
if (strlen($name) > 0) {}
if ($name) {}
if (is_array($mein_array)) foreach ($mein_array ...) {}
foreach ($mein_array ...) {}
if (strpos("-", "hallo") === false) {}
if (!strpos("-", "hallo")) {}
Ab Version 5.3 soll PHP Namensräume unterstützen, bis dahin muss man versuchen sich diese selbst zu schaffen, in dem man Dateien nach ihrem Zweck benennt.
include("helper_functions.inc.php"); include("modules/test/test.class.php"); $test = new Test();
Dank der formatfreien C-Syntax ist es auch in PHP möglich Blöcke zu definieren oder diese wegzulassen. Bei Anweisungen die normalerweise Blöcke benötigen, ist es zwingend erforderlich dies auch zu tun. Um die Schreibweise zu kürzen und übersichtlicher zu gestalten sollten wenn schon Einzelanweisungen direkt dahinter stehen.
if ($variable == 1) { echo "ich bin wahr"; }
if ($variable == 1) echo "ich bin wahr";
if ($variable == 1) echo "ich bin wahr";
Hinweis: Ein sehr interessanter Artikel über die wahre Intention der ungarischen Notation: http://www.joelonsoftware.com/articles/Wrong.html
Entsprechende Einstellung in php.ini. Code in kurzen Tags wird ignoriert.
short_open_tag = Off
<?php echo "Hallo Welt"; ?>
<?="Hallo Welt" ?>
Viele Skripte setzen die Existenz von globalen Variablen vorraus. Dies ist nicht nur unsauber sondern gefährlich. Das Registrieren von globalen Variablen ist zwingend in der php.ini abzustellen:
register_globals = Off
echo $_SERVER["DOCUMENT_ROOT"];
echo $DOCUMENT_ROOT;
$variable = $_GET["variable"];
echo $variable;
echo $_GLOBALS["variable"];
global $variable;
Funktionen haben zu bestimmen, ob sie eine Referenz benötigen, nicht der Aufruf. Die Option call by reference ist standardmäßig in neueren PHP-Versionen abgeschalten. Die entsprechende Option in der php.ini lautet:
allow_call_time_pass_reference = Off
function foo(&$bar) { return 0; }
foo(&$bar);
Einige PHP-Funktionen werfen Fehler. Es gibt einen Grund dafür! Deswegen sollte einer Ausgabe niemals unterdrückt, sondern behandelt oder besser: vermieden werden.
if (is_writable($filename)) { $fp = fopen($filename, "w"); fwrite($fp, "hallo"); fclose($fp); }
Mit dem exec-Befehl kann man viel anstellen, z.B. das gesamte Web-Verzeichnis löschen. Deshalb sollte das Starten von Befehlen mit dem Safe-Mode in der php.ini eingeschalten werden.
safe_mode = On
Demnach dürfen nur noch Programme gestartet werden, die unterhalb eines sicheren Verzeichnisses liegen, welches man in der php.ini folgendermaßen aktiviert.
safe_mode_exec_dir = /opt/php_safe_exec_dir
Hier sollte man keinesfalls /usr/bin oder sonstige Verzreichnisse eintragen, da ja der Sinn dieser Einschränkung ad absurdum geführt werden würde. Stattdessen sollte man dieses Verzeichnis anlegen und alle Befehle mit einem symbolischen Link dort hinein verknüpfen. Die Programme werden unter dem Apache-Benutzer (www-data/wwwrun) ausgeführt.
Für Dateisystemoperationen sind die PHP-eigenen Klassen und Funktionen vorzuziehen. Sollte man dennoch mal in die Gelegenheit kommen, einen exec-Befehl auszuführen, dann muss der Befehl zwingend mit escapeshellcmd maskiert werden.
exec(escapeshellcmd($mein_befehl));
exec($mein_befehl);
Außerdem dürfen nur noch Dateien eingebunden werden, die der open basedir restriction unterliegen.
Potentielle Sicherheitsprobleme für Außenstehende sind immer leicht an den Fehlern zu erkennen die PHP auswirft. Dies ist aber ein enormes Sicherheitsrisiko. Deshalb wird das error reporting abgeschalten. In den Apache error_logs sind diese aber weiterhin sichtbar.
display_errors = Off error_reporting = E_ALL & ~E_NOTICE
Dies lässt sich jedoch mit einer .htaccess Datei temporär (zu Berichtigungszwecken) aktivieren.
php_flag display_errors on
PHP bietet die Möglichkeit Dateien einzubinden, die außerhalb des Servers liegen. Externe Server sind aber niemals vertrauenswürdig, deswegen wird diese Möglichkeit in der php.ini abgeschalten.
allow_url_fopen = Off allow_url_include = Off