Fork me on GitHub

Willkommen

Im Web findet man eine Menge von veralteten Informationen, mit der neue PHP-Anwender in die Irre geführt werden und die schlechte Methoden und schlechten Code verbreiten. Das kann nicht so weitergehen. PHP: Der richtige Weg ist eine einfach lesbare Schnellreferenz für PHP und enthält die besten Verfahren, anerkannte Code-Standards und Links zu maßgeblichen Anleitungen im Web.

Übersetzungen

PHP: Der richtige Weg wurde in viele verschiedene Spachen übersetzt:

Haftungsausschluss

Es gibt keinen vorschriftsmäßigen Einsatz von PHP. Abgesehen davon ist diese Website eine bescheidene Darstellung der besten Methoden, möglicher Alternativen und guter Information. Ihr Ziel ist es, neue PHP-Entwickler anzuleiten und altgediente Profis mit frischen Ideen zu versorgen.

Dieses Dokument lebt und wird fortlaufend mit weiteren hilfreichen Informationen und Beispielen ergänzt, sobald sie verfügbar werden.

Mitarbeiten

Hilf mit, diese Website zur besten Informationsquelle für PHP-Programmierer zu machen! Arbeite auf GitHub mit.

Verbreite die Botschaft!

Für PHP: Der richtige Weg gibt es Bannergrafiken, die du auf deiner Website verwenden kannst. Demonstriere deine Unterstützung und zeige neuen PHP-Entwicklern, wo sie gute Informationen finden können!

Bannergrafiken

Zurück zum Start

Erste Schritte

Verwende die aktuelle stabile Version (5.5)

Wenn du gerade deine ersten Schritte mit PHP machst, stelle sicher, dass du mit der aktuellen stabilen Version von PHP 5.5 beginnst. PHP hat große Fortschritte gemacht und leistungsfähige neue Features im Lauf der letzten Jahre dazugewonnen. Lass dich nicht von dem kleinen Unterschied in der Versionsnummer zwischen 5.2 und 5.5 in die Irre führen - er bringt große Verbesserungen. Auf php.net findest du die Dokumentation zu Funktionen und deren Anwendung.

Eingebauter Webserver

Du kannst mit dem Erlernen von PHP beginnen, ohne einen vollwertigen Webserver zu installieren und zu konfigurieren (erfordert PHP 5.4+). Gib diesen Befehl auf der Konsole im Web-Wurzelverzeichnis deines Projekts ein, um den Server zu starten:

> php -S localhost:8000

Installation auf dem Mac

Eine leicht veraltete Version von PHP ist im Lieferumfang von OSX enthalten. Lion wird mit PHP 5.3.6 ausgeliefert, Mountain Lion mit 5.3.10.

Um PHP auf OSX zu aktualisieren, kannst du einen der vielen Paketmanager für den Mac einsetzen. php-osx von Liip ist empfehlenswert.

Eine weitere Möglichkeit ist, PHP selbst zu kompilieren. In diesem Fall musst du sicherstellen, dass entweder Xcode oder Apples Ersatz “Command Line Tools for Xcode” aus Apples Developer Center installiert sind.

MAMP ist ein vollständiges Komplettpaket inklusive PHP, dem Webserver Apache und der Datenbank MySQL unter einer hübschen grafischen Oberfläche.

Installation unter Windows

PHP für Windows wird über mehrere Wege angeboten. Du kannst die Binaries herunterladen, und bis vor Kurzem konntest du PHP auch über eine ‘.msi’-Datei installieren. Diese Installationsdatei wird seit PHP 5.3.0 nicht mehr unterstützt.

Zum Erlernen und für die lokale Entwicklung kannst du den in PHP 5.4 eingebauten Webserver verwenden und dich nicht weiter um die Konfiguration kümmern. Wenn du lieber ein “Komplettpaket” mit einem vollständigen Webserver und MySQL einsetzen möchtest, verhelfen dir Werkzeuge wie der Web Platform Installer, Zend Server CE, XAMPP und WAMP schnell zu einer Entwicklungsumgebung unter Windows. Bitte beachte, dass diese Werkzeuge kleine Unterschiede zur Produktivumgebung haben und du darauf achten solltest, wenn du unter Windows entwickelst und auf Linux ausrollst.

Wenn deine Produktionssite unter Windows läuft, liefert IIS7 die stabilste und leistungsfähigste Grundlage. Du kannst phpmanager (ein GUI-Plugin für IIS7) für die einfache Konfiguration und Verwaltung von PHP einsetzen. IIS7 enthält FastCGI, daher musst du nur PHP als FastCGI-Handler konfigurieren. Es gibt einen spezialisierten Bereich auf iis.net mit Unterstützung und weiteren Informationen.

Vagrant

Der Betrieb einer Anwendung in zwischen Entwicklung und Produktion unterschiedlichen Umgebungen kann zu seltsamen Bugs führen. Ein Team von Entwicklern auf dem selben Versionsstand aller Bibliotheken zu halten, kann ebenfalls umständlich werden.

Du solltest den Einsatz einer virtuellen Maschine erwägen, wenn du unter Windows entwickelst und auf Linux oder ein anderes Nicht-Windows-Betriebssystem ausrollst oder in einem Team entwickelst. Das klingt kompliziert, aber mit Hilfe von Vagrant kannst du eine einfache virtuell Maschine in wenigen Schritten einrichten. Diese Basismaschinen kannst du anschließend manuell aufsetzen oder Software wie Puppet or Chef zur “Provisionierung” einsetzen. Eine Basismaschine zu provisionieren, ist eine gute Methode um sicherzustellen, dass mehrere Maschinen identisch konfiguriert sind und reduziert den Bedarf von komplizierten Checklisten für das Setup. Du kannst eine Basismaschine jederzeit zerstören und ohne viele manuelle Schritte mit einer frischen Installation neu aufsetzen.

Vagrant erstellt geteilte Verzeichnisse, um den Code zwischen dem Host und den virtuellen Maschinen zu verteilen. Damit kannst du den Code auf der Hostmaschine bearbeiten und in den virtuellen Maschinen ablaufen lassen.

Zurück zum Start

Stilregeln für den Code

Die PHP-Gemeinschaft ist groß und vielfältig und besteht aus unzähligen Bibliotheken, Frameworks und Bausteinen. Üblicherweise wählen PHP-Entwickler mehrere davon aus und kombinieren sie in einem einzelnen Projekt. Es ist wichtig, dass PHP-Code einem gemeinsamen Stil folgt, um Entwicklern die Kombination von verschiedenen Bibliotheken innerhalb ihrer Projekte zu erleichtern.

Die Framework Interop Group hat eine Reihe von Stil-Empfehlungen unter den Namen PSR-0, PSR-1 und PSR-2 vorgeschlagen. Trotz des seltsamen Namens sind diese Empfehlungen nur ein Satz von Regeln, den einige Projekte wie Drupal, Zend, Symfony, CakePHP, phpBB, AWS SDK, FuelPHP, Lithium und andere in ersten Ansätzen folgen. Du kannst sie für deine eigenen Projekte anwenden oder damit fortfahren, deinen persönlichen Stil zu pflegen.

Im Idealfall solltest du PHP-Code schreiben, der sich an einen bekannten Standard hält. Das kann eine Kombination der PSRs oder einer der Code-Standards von PEAR oder Zend sein. Das bedeutet, dass andere Entwickler sich einfach einlesen und mit deinem Code arbeiten können und Anwendungen konsistent wirken, selbst wenn sie viele Bausteine von dritter Seite benutzen.

Du kannst deinen Code mit PHP_CodeSniffer gegenüber einer dieser Empfehlungen prüfen oder Plugins für Texteditoren wie Sublime Text 2 einsetzen, um Rückmeldungen gleich während der Bearbeitung zu erhalten.

Mit Fabien Potenciers PHP Coding Standards Fixer kannst du automatisch Code modifizieren, sodass er mit diesen Standards konform ist, und sparst dir somit die händische Bearbeitung.

Englisch ist die bevorzugte Sprache für alle Symbolnamen und Code-Infrastruktur. Kommentare können in jeder Sprache geschrieben werden, die von den derzeitigen und künftigen Beteiligten gelesen werden kann.

Zurück zum Start

Das Beste der Sprache

Programmierparadigmen

PHP ist eine flexible, dynamische Sprache, die unterschiedliche Programmiertechniken unterstützt. Sie hat sich über die Jahre dramatisch entwickelt, speziell mit der Ergänzung um ein solides objektorientiertes Modells in PHP 5.0 (2004), anonyme Funktionen und Namespaces in PHP 5.3 (2009) und Traits in PHP 5.4 (2012).

Objektorientierte Programmierung

PHP besitzt eine weitgehend vollständige Menge von objektorientierten Eigenschaften inklusive der Unterstützung von Klassen, Vererbung, Konstruktoren, Cloning, Exceptions und mehr.

Funktionale Programmierung

PHP unterstützt Funktionen erster Klasse. Das heißt, dass Funktionen an Variablen zugewiesen werden können. Sowohl benutzerdefinierte als auch eingebaute Funktionen können über eine Variable referenziert und dynamisch aufgerufen werden. Funktionen können als Argumente an andere Funktionen übergeben werden.

Rekursion, eine Eigenschaft, die den Aufruf einer Funktion durch sich selbst erlaubt, wird von der Sprache unterstützt, aber der Großteil des PHP-Codes hat den Schwerpunkt auf Iteration.

Neue anonyme Funktionen mit der Unterstützung von Closures sind seit PHP 5.3 (2009) vorhanden.

Mit PHP 5.4 kam die Fähigkeit, Closures an den Gültigkeitsbereich eines Objekts zu binden, und die verbesserte Unterstützung für Callables, die seither gleichberechtigt mit anonymen Funktionen in fast allen Fällen einsetzbar sind.

Meta-Programmierung

PHP unterstützt verschiedene Formen der Meta-Programmierung über Mechanismen wie das Reflection API und magische Methoden. Die magischen Methoden wie etwa __get(), __set(), __clone(), __toString(), __invoke() etc. erlauben Entwicklern, sich in das Verhalten von Klassen einzuhängen. Ruby-Entwickler behaupten oft, dass in PHP method_missing fehlt, aber diese ist als __call() and __callStatic() vorhanden.

Namespaces

Wie oben erwähnt besteht die PHP-Gemeinschaft aus vielen Entwicklern, die eine Menge Code produzieren. Das bedeutet, dass der PHP-Code aus einer Bibliothek die selben Klassennamen verwenden kann wie der Code einer anderen Bibliothek. Wenn beide Bibliotheken im selben Namensraum verwendet werden, entstehen Kollisionen und verursachen Probleme.

Namespaces lösen dieses Problem. Laut der Beschreibung im PHP-Handbuch können Namespaces mit den Verzeichnissen vom Dateisystemen verglichen werden, die Namensräume für Dateien bilden; zwei Dateien mit dem selben Namen können in unterschiedlichen Verzeichnissen existieren. Ebenso können zwei PHP-Klassen mit dem selben Namen in getrennten PHP-Namespaces koexistieren. So einfach ist das.

Für dich ist wichtig, deinen Code in Namensräumen zu ordnen, damit er von anderen Entwicklern ohne Sorge um mögliche Kollisionen mit anderen Bibliotheken verwendet werden kann.

Ein empfohlene Methode zum Einsatz von Namespaces ist in PSR-0 mit dem Ziel einer standardisierten Datei-, Klassen- und Namespace-Konvention für Plug-and-Play-Code umrissen.

Standard PHP Library

Die “Standard PHP Library” (SPL) ist mit PHP gebündelt und bietet eine Sammlung von Klassen und Schnittstellen. Sie besteht hauptsächlich aus häufig benötigten Klassen für Datenstrukturen wie Stack, Queue oder Heap, sowie Iteratoren, die diese Datenstrukturen oder deine eigenen Klassen, die die SPL-Schnittstellen implementieren, durchlaufen können.

Schnittstelle für die Befehlszeile

PHP wurde primär für die Erstellung von Web-Anwendungen geschaffen, aber es ist auch beim verfassen von Befehlszeilenprogrammen (CLI; command line interface) nützlich. PHP-Programme für die Befehlszeile können dir helfen, allgemeine Aufgaben wie Softwaretests, Ausrollung und Administratives zu automatisieren.

CLI-PHP-Programme sind mächtig, weil sie den Code deiner Anwendung direkt ohne Web-Oberfläche benutzen können. Achte nur darauf, dass deine CLI-Scripts nicht im öffentlichen Webverzeichnis liegen!

Versuche, PHP von der Befehlszeile aus aufzurufen:

> php -i

Die Option -i gibt die PHP-Konfiguration ähnlich wie die Funktion phpinfo aus.

Die Option -a startet eine interaktive Shell ähnlich wie IRB in Ruby oder Pythons interaktive Shell. Es gibt einige andere nützliche Optionen für die Befehlszeile.

Schreiben wir doch ein CLI-Programm für “Hello, $name”. Erstelle eine Datei hello.php und gib diesen Code in die Datei ein:

<?php
if ($argc !== 2) {
    echo "Usage: php hello.php [name].\n";
    exit(1);
}
$name = $argv[1];
echo "Hello, $name\n";

PHP erstellt zwei spezielle Variablen auf Basis der Argumente, mit denen dein Script gestartet wird. $argc ist eine Integer-Variable und enthält die Anzahl der Argumente; $argv ist ein eine Array-Variable, die den Wert jedes Arguments enthält. Das erste Argument ist immer der Name deines PHP-Scripts, in unserem Fall also hello.php.

Der Ausdruck exit() wird mit einer Zahl ungleich Null aufgerufen, um die Shell davon zu informieren, dass der Befehl gescheitert ist. Gebräuchliche Exitcodes findet man hier.

Starte unser Script von der Befehlszeile:

> php hello.php
Usage: php hello.php [name]
> php hello.php world
Hello, world

XDebug

Eines der nützlichsten Werkzeuge der Softwareentwicklung ist ein guter Debugger. Damit kannst du den Ablauf des Codes verfolgen und den Inhalt des Stacks beobachten. XDebug, der Debugger für PHP, kann in verschiedenen IDEs für Breakpoints und zur Stackinspektion eingesetzt werden. Er ermöglicht auch Werkzeugen wie PHPUnit oder KCacheGrind, die Codeabdeckung zu analysieren und den Code zu profilieren.

Wenn du dich in einer Klemme befindest und trotz einem Rückgriff auf var_dump/print_r keine Lösung findest, brauchst du vielleicht den Debugger.

Die Installation von XDebug kann kompliziert sein, aber eine seiner wichtigsten Fähigkeiten ist “Remote Debugging” - wenn du lokal entwickelst und dann in einer anderen VM oder auf einem anderen Server testest, ist Remote Debugging das Feature, das du jedenfalls sofort einschalten willst.

Traditionellerweise ergänzt du den Apache-Vhost oder die Datei .htaccess mit diesen Werten:

php_value xdebug.remote_host=192.168.?.?
php_value xdebug.remote_port=9000

“remote host” “remote port” entsprechen deinem lokalen Computer und Port, wie du ihn in der IDE konfigurierst. Anschließend musst du nur deine IDE in die Betriebsart “listen for connections” bringen und diese URL aufrufen:

//your-website.example.com/index.php?XDEBUG_SESSION_START=1

Deine IDE wird nun den aktuellen Zustand deines Script während der Ausführung abhören und dir erlauben, Breakpoints zu setzen und die Werte im Speicher zu untersuchen.

Zurück zum Start

Verwaltung von Abhängigkeiten

Es gibt eine unüberschaubare Menge von PHP-Bibliotheken, Frameworks und Bausteinen, aus denen man wählen kann. In deinem Projekt wirst du wahrscheinlich mehrere davon einsetzen. Bis vor Kurzem hatte PHP keine Methode um diese Projektabhängigkeiten zu verwalten. Selbst wenn du diese händisch verwaltet hättest, musstest du dich um Autoloading kümmern. Das ist vorbei.

Zur Zeit gibt es zwei große Paketverwaltungssysteme für PHP - Composer und PEAR. Welches ist das richtige für dich? Beide, lautete die Antwort.

Allgemein sind Pakete aus Composer nur in den Projekten verfügbar, die du explizit angibst, während Pakete aus PEAR in allen deinen PHP-Projekten verfügbar sind. Auf den ersten Blick mag der PEAR-Ansatz einfacher erscheinen, aber der projektspezifische Zugang zu Abhängigkeiten hat Vorteile.

Composer und Packagist

Composer ist ein brillanter Abhängigkeitsmanager für PHP. Führe deine Abhängigkeiten in der Datei composer.json auf, und nach ein paar einfachen Befehlen lädt Composer automatisch die Abhängigkeiten deines Projekts herunter und setzt den Autoloader für dich auf.

Viele PHP-Bibliotheken sind bereits mit Composer kompatibel und bereit für den Einsatz in deinem Projekt. Diese “Pakete” werden bei Packagist gelistet, dem offiziellen Verzeichnis von mit Composer kompatiblen PHP-Bibliotheken.

Composer installieren

Du kannst Composer lokal in deinem aktuellen Arbeitsverzeichnis installieren (das wird nicht mehr empfohlen), oder global etwa in /usr/local/bin. Nehmen wir einmal an, du möchtest Composer lokal installieren. Gib diese Befehle im Wurzelverzeichnis deines Projekts ein:

curl -s https://getcomposer.org/installer | php

Damit wird composer.phar (ein binäres PHP-Archiv) heruntergeladen. Du kannst es mit php ausführen, um die Abhängigkeiten deines Projekts zu verwalten. Bitte beachte: Lies den Code zuerst online zur Sicherheitsprüfung, bevor du ihn direkt an den Interpreter weitergibst.

Composer manuell installieren

Die manuelle Installation von Composer ist eine Technik für Fortgeschrittene. Es gibt verschiedene Gründe, warum ein Entwickler diese Methode gegenüber der interaktiven Installationsroutine bevorzugen würde. Die interaktive Installation überprüft deine PHP-Umgebung auf:

Da eine manuelle Installation keine dieser Bedingungen prüft, muss du entscheiden, ob die Nachteile gerechtfertigt sind. Falls das zutrifft, kannst du Composer so manuell installieren:

curl -s https://getcomposer.org/composer.phar -o $HOME/local/bin/composer
chmod +x $HOME/local/bin/composer

Der Pfad $HOME/local/bin oder ein anderes Verzeichnis deiner Wahl sollten in deiner Umgebungsvariablen $PATH enthalten sein. Damit wird der Befehl composer verfügbar.

Jedes Vorkommen von php composer.phar install in der Dokumentation kannst du mit folgendem Befehl ersetzen:

composer install

Abhängigkeiten definieren und installieren

Composer verfolgt die Abhängigkeiten deines Projekts in einer Datei namens composer.json. Du kannst diese Datei händisch oder mit Composer verwalten. Der Befehl php composer.phar require fügt eine Projektabhängigkeit hinzu. Wenn die Datei composer.json noch nicht existiert, wird sie erstellt. Im folgenden Beispiel wird Twig als Abhängigkeit zu deinem Projekt hinzugefügt. Starte es im Wurzelverzeichnis deines Projekts, nachdem du composer.phar heruntergeladen hast:

php composer.phar require twig/twig:~1.8

Alternativ führt dich der Befehl php composer.phar init durch die Erstellung einer vollständigen composer.json für dein Projekt. In jedem Fall kannst du nach der Erzeugung der Datei composer.json Composer anweisen, die Abhängigkeiten deines Projekts in das Verzeichnis vendors/ herunterzuladen und zu installieren. Das trifft auch auf heruntergeladene Projekte zu, die selbst bereits eine Datei composer.json bereitstellen:

php composer.phar install

Als nächsten Schritt füge die folgende Zeile zur primären PHP-Datei deines Projektes hinzu; damit weist du PHP an, den Autloader von Composer für deine Projektabhängigkeiten einzusetzen.

<?php
require 'vendor/autoload.php';

Du kannst jetzt Projektabhängigkeiten verwenden, und sie werden automatisch heruntergeladen.

Abhängigkeiten aktualisieren

Composer erzeugt eine Datei composer.lock, in der die genauen Versionen jedes Pakets zu dem Zeitpunkt gespeichert sind, an dem du das erste Mal php composer.phar install ausgeführt hast. Wenn du dein Projekt mit anderen Programmierern teilst und die Datei php composer.phar install in das verteilte Produkt aufnimmst, erhalten sie dieselbe Version wie du. Starte php composer.phar update, um die Abhängigkeiten zu aktualisieren.

Das ist auch sehr nützlich, falls du deine Versionsansprüche flexibel definiert hast. Beispielsweise bedeutet eine erforderliche Version von ~1.8 “irgend eine Version, die neuer ist als 1.8, aber niedriger als 2.0.x-dev”. Der Composer-Befehl php composer.phar update wird alle Abhängigkeiten auf die neueste Version aktualisieren, welche die definierten Einschränkungen erfüllen.

Abhängigkeiten auf Sicherheitsprobleme prüfen

Der Security Advisories Checker ist ein Webdienst und ein Befehlszeilenwerkzeug. Er untersucht die Datei composer.lock und berichtet, ob eine Abhängigkeit aktualisiert werden muss.

PEAR

Ein weiterer altgedienter Paketverwalter für PHP-Programmierer ist PEAR. Er funktioniert weitgehend wie Composer mit ein paar bemerkenswerten Unterschieden.

PEAR erfordert, dass jedes Paket eine bestimmte Struktur einhält. Der Autor eines Pakets muss es also für den Einsatz mit PEAR vorbereiten. Es ist nicht möglich, ein Projekt mit PEAR einzusetzen, das nicht dafür vorgesehen wurde.

PEAR installiert Pakete global. Das heißt, dass Pakete nach einer einmaligen Installation allen Projekten auf dem Server zur Verfügung stehen. Das kann günstig sein, wenn viele Projekte auf dem selben Paket in der selben Version basieren, kann aber zu Versionskonflikten zwischen zwei Paketen führen.

PEAR installieren

PEAR kann man installieren, indem man die Phar-Installation herunterlädt und ausführt. Die PEAR-Dokumentation enthält detaillierte Installationsanleitungen für jedes Betriebssystem. Debian und Ubuntu beinhalten zum Beispiel das Paket php-pear für apt.

Ein Paket installieren

Wenn das Paket in der Paketliste für PEAR geführt wird, kannst du es über seinen offiziellen Namen installieren:

pear install foo

Wird das Paket auf einem anderen Channel angeboten, musst du zuerst discover für den Channel ausführen und ihn auch bei der Installation angeben. Mehr dazu findest du in der Channel-Dokumentation.

Zurück zum Start

Programmiermethoden

Grundlagen

PHP ist eine umfangreiche Sprache, mit der Programmierer Code schnell und effizient erstellen können. Mit zunehmendem Gebrauch der Sprache vergessen wir oft die Grundlagen im Austausch gegen Abkürzungen und schlechte Gewohnheiten. Dieser Abschnitt dient dazu, Programmierer wieder an grundlegende Programmiermethoden von PHP zu erinnern und dieses Problem zu bekämpfen.

Datum und Zeit

PHP beinhaltet eine Klasse namens DateTime, die beim Lesen, Schreiben, Vergleichen und Berechnen von Datum und Zeit hilft. Es gibt neben DateTime viele weitere Funktionen mit Bezug zu Datum und Zeit in PHP, aber die Klasse bietet eine schöne objektorientierte Schnittstelle für die häufigsten Anwendungsfälle. Sie kann auch Zeitzonen verarbeiten, das ist allerdings nicht Inhalt dieser kurzen Einführung.

Konvertiere einen unformatierten Datums- und Zeitstring mit der Factory-Methode createFromFormat() oder verwende new \DateTime für die aktuelle Zeit und das aktuelle Datum, um mit DateTime zu beginnen. Verwende die Methode format(), um ein DateTime-Objeckt wieder in einen String zur Ausgabe zu konvertieren.

<?php
$raw = '22. 11. 1968';
$start = \DateTime::createFromFormat('d. m. Y', $raw);

echo 'Start date: ' . $start->format('m/d/Y') . "\n";

Die Klasse DateInterval ermöglicht Berechnungen mit DateTime. DateTime besitzt Methoden wie add() and sub(), die ein DateTime-Intervall als Argument akzeptieren. Schreibe keinen Code, der annimmt, dass jeder Tag dieselbe Zahl von Sekunden dauert. Sowohl Sommerzeit-/Winterzeitwechsel als auch Zeitzonenwechsel verletzen diese Annahme. Verwende stattdessen DateInterval. Verwende die Methode diff(), um Datumsunterschiede zu berechnen. Das Ergebnis ist ein DateInterval, das sehr einfach anzuzeigen ist.

<?php
// create a copy of $start and add one month and 6 days
$end = clone $start;
$end->add(new \DateInterval('P1M6D'));

$diff = $end->diff($start);
echo 'Difference: ' . $diff->format('%m month, %d days (total: %a days)') . "\n";
// Difference: 1 month, 6 days (total: 37 days)

Du kannst herkömmliche Vergleichsoperatoren auf DateTime-Objekte anwenden:

<?php
if ($start < $end) {
    echo "Start is before end!\n";
}

Ein letztes Beispiel zeigt die Klasse DatePeriod. Sie wird verwendet, um über wiederkehrende Ereignisse zu iterieren. Sie akzeptiert zwei DateTime-Objekte für Beginn und Ende und ein Intervall und gibt alle Ereignisse dazwischen zurück.

<?php
// output all thursdays between $start and $end
$periodInterval = \DateInterval::createFromDateString('first thursday');
$periodIterator = new \DatePeriod($start, $periodInterval, $end, \DatePeriod::EXCLUDE_START_DATE);
foreach ($periodIterator as $date) {
    // output each date in the period
    echo $date->format('m/d/Y') . ' ';
}

Entwurfsmuster

Beim Entwurf einer Anwendung ist es hilfreich, gebräuchliche Entwurfsmuster für Code und die Gesamtstruktur des Projekts zu verwenden. Bekannte Muster machen die Verwaltung des Codes einfacher und erleichtern anderen Entwicklern, Zusammenhänge zu verstehen.

Wird ein Framework eingesetzt, basiert der Großteil der übergeordneten Code- und Projektstruktur auf diesem Framework, und viele Entscheidungen sind vorweg getroffen. Aber die Verantwortung für die Auswahl der besten Muster für den eigenen Code liegt bei dir. Wenn du andererseits kein Framework einsetzt, musst du selbst Muster finden, die zum Typ und zur Größe der Anwendung passen.

Exceptions

Exceptions sind ein Standardbestandteil moderner populärer Programmiersprachen, werden aber oft von PHP-Programmierern übersehen. Sprachen wie Ruby legen viel Gewicht auf Exceptions, so dass viele Fehler wie etwa ein erfolgloser HTTP-Request, eine falsche Datenbankabfrage oder eine fehlende Grafikdatei die Anzeige von Exceptions am Bildschirm auslösen und so auf Fehler hinweisen.

PHP selbst ist relativ nachlässig, so dass ein file_get_contents() üblicherweise nur zu einem FALSE und einer Warnung führt. Viele ältere Frameworks wie CodeIgniter geben auch nur FALSE zurück, schreiben eine Nachricht in ihr Fehlerlog und erlauben dir den Aufruf einer Methode wie $this->upload->get_error(), um die Ursache des Fehlers zu finden. Das Problem dabei ist, dass du nach dem Fehler fragen und in der Dokumentation nach der Fehlermethode für diese Klasse suchen musst, statt es äußerst offensichtlich zu machen.

Ein weiteres Problem besteht, wenn Klassen automatisch Fehler auslösen und den Prozess beenden. Wenn du so vorgehst, hinderst du andere Entwickler daran, Fehler dynamisch zu behandeln. Exceptions sollten ausgelöst werden, um Entwickler auf Fehler hinzuweisen und ihnen Gelegenheit zu geben, darauf zu reagieren. Ein Beispiel:

<?php
$email = new Fuel\Email;
$email->subject('My Subject');
$email->body('How the heck are you?');
$email->to('guy@example.com', 'Some Guy');

try
{
    $email->send();
}
catch(Fuel\Email\ValidationFailedException $e)
{
    // The validation failed
}
catch(Fuel\Email\SendingFailedException $e)
{
    // The driver could not send the email
}

SPL Exceptions

Die generische Klasse Exception enthält sehr wenig Kontext für das Debugging durch den Entwickler. Zur Erleichterung kann man über eine Unterklassen der generischen Klasse Exception einen spezialisierten Exception-Typ schaffen:

<?php
class ValidationException extends Exception {}

So kannst du mehrere catch-Blöcke einrichten und unterschiedliche Exceptions auch unterschiedlich behandeln. Das kan zu einer Vielzahl von benutzerdefinierten Exceptions führen, von denen einige durch den Einsatz von SPl Exceptions aus der SPL-Erweiterung vermeidbar sind.

Zum Beispiel könnte die magische Methode __call() beim Aufruf einer ungültigen Methode throw new BadFunctionCallException; aufrufen, statt die Standard-Exception oder eine benutzerdefinierte Exception auszulösen.

Zurück zum Start

Datenbanken

Oft wird dein PHP-Code eine Datenbank verwenden, um Informationen dauerhaft zu speichern. Es gibt einige Möglichkeiten, um dich mit deiner Datenbank zu verbinden und mit ihr zu interagieren. Die empfohlene Auswahl bis PHP 5.1.0_ waren die nativen Treiber wie mysql, mysqli, pgsql etc.

Native Treiber sind gut geeignet, wenn du nur ein Datenbanksystem in deiner Anwendung einsetzt. Wenn du aber zum Beispiel MySQL und ein wenig von MSSQL verwenden oder dich mit einer Oracle-Datenbank verbinden möchtest, kannst du nicht dieselben Treiber verwenden. Du musst ein völlig neues API für jedes Datenbanksystem erlernen - und das kann albern werden.

Zusätzlich ist zu sagen, dass die MySQL-Erweiterung für PHP nicht mehr aktiv weiterentwickelt wird und der offizielle Status seit PHP 5.4.0 “langfristige Abkündigung” lautet. Das bedeutet, dass sie im Zug der nächsten Releases entfernt werden wird. Sie könnte also mit PHP 5.6 (oder welche Version auch immer nach 5.5 kommen wird) verschwinden. Setzt du mysql_connect() und mysql_query() in deiner Anwendung ein, wirst du den Code dann umschreiben müssen. Die beste Wahl ist ist es, in deinen Anwendungen während eines geplanten Entwicklungszyklus mysql durch mysqli oder PDO zu ersetzen und so einer späteren erzwungenen Umstellung auszuweichen. Vermeide die mysql-Erweiterung bei einem neuen Projekt: Verwende die mysqli-Erweiterung oder PDO.

PDO

PDO ist eine Bibliothek zur Datenbankabstraktion - seit Version 5.1.0 in PHP integriert - die eine gemeinsame Schnittstelle zu vielen verschiedenen Datenbanksystemen bietet. PDO übersetzt keine SQL-Abfragen und emuliert keine fehlenden Eigenschaften; es dient rein der Verbindung zu mehreren Datenbanksystemen mit einem einheitlichen API.

Wichtiger noch: PDO erlaubt dir, externe Eingaben wie zum Beispiel IDs sicher in deine SQL-Abfragen einzubauen, ohne dich über SQL-Injection-Angriffe zu sorgen. Das geschieht über PDO-Statements und gebundene Parameter.

Nehme wir an, dass ein PHP-Script eine numerische ID als Query-Parameter annimmt. Diese ID soll verwendet werden, um einen Benutzerdatensatz aus der Datenbank zu lesen. Hier ist der falsche Weg, das zu erledigen:

<?php
$pdo = new PDO('sqlite:users.db');
$pdo->query("SELECT name FROM users WHERE id = " . $_GET['id']); // <-- NO!

Das ist schrecklicher Code. Du fügst einen ungefilterten Query-Parameter in eine SQL-Abfrage ein. Du wirst innerhalb von Sekunden gehackt. Stell dir vor, dass ein Hacker einen erfinderischen id-Parameter über eine URL wie //domain.com/?id=1%3BDELETE+FROM+users übergibt. Das setzt die Variable $_GET['id'] auf 1;DELETE FROM users und löscht so alle deine User! Du solltest stattdessen die ID-Eingabe über PDO-gebundene Parameter reinigen.

<?php
$pdo = new PDO('sqlite:users.db');
$stmt = $pdo->prepare('SELECT name FROM users WHERE id = :id');
$stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT); //<-- Automatically sanitized by PDO
$stmt->execute();

Das ist korrekter Code. Er verwendet einen gebundenen Parameter in einem PDO-Ausdruck. Das bereinigt die externe Eingabe, bevor sie an die Datenbank weitergegeben wird, und verhindert so potentielle SQL-Injection-Angriffe.

Du solltest dir auch darüber klar sein, dass Datenbankverbindungen Ressourcen verbrauchen und es kann schon vorkommen, dass diese Ressourcen erschöpft werden, wenn Verbindungen nicht explizit geschlossen wurden. Das trifft aber vor allem auf andere Sprachen zu. Mit PDO kannst du eine Verbindung implizit schließen, indem du das Objekt freigibst. Dazu lösche alle verbleibenden Referenzen, indem du sie auf NULLsetzt. Wenn du das nicht ausdrücklich machst, schließt PHP die Verbindung automatisch am Ende des Scripts, sofern du nicht persistente Verbindungen benutzt.

Abstraktionsschichten

Viele Frameworks enthalten ihre eigenen Abstraktionsschichten, die teilweise auf PDO aufbauen. Diese emulieren oft fehlende Eigenschaften eines Datenbanksystems, indem sie Abfragen in PHP-Methoden kleiden und so die Datenbank tatsächlich abstrahieren. Damit entsteht natürlich ein wenig Overhead, der aber beim Bau einer zwischen MySQL, PostgreSQL und SQLite portablen Anwendung seine Berechtigung hat.

Einige Abstraktionsschichten wurden gemäß den Namespace-Standards nach PSR-0 entwickelt und können daher in jede Anwendung eingebaut werden:

Zurück zum Start

Sicherheit

Sicherheit von Webanwendungen

Böse Menschen sind bereit und willig, deine Webanwendung auszubeuten. Es ist wichtig, die notwenigen Vorsichtsmaßnahmen zu treffen und die Sicherheit deiner Webanwendung zu verstärken. Zum Glück haben die netten Kollegen von The Open Web Application Security Project (OWASP) eine umfassende Liste bekannter Sicherheitsprobleme und Methoden zum Schutz zusammengestellt. Das ist Pflichtlektüre für jeden sicherheitsbewussten Entwickler.

Passwort-Hashing

Früher oder später baut jeder eine PHP-Anwendung, die angemeldete Benutzer benötigt. Benutzernamen und Passwörter werden in einer Datenbank gespeichert und später verwendet, um den Benutzer bei der Anmeldung zu authentifizieren.

Es ist wichtig, Passwörter vor dem Speichern korrekt zu hashen. Passwort-Hashing ist eine nicht umkehrbare Einbahnfunktion, die auf das Passwort des Benutzers angewandt wird. Sie erzeugt einen String mit fester Länge, der nicht mit vertretbarem Aufwand entschlüsselt werden kann. Das bedeutet, dass du einen Hashwert mit einem zweiten vergleichen kannst, um festzustellen, ob beide den selben Quellstring repräsentieren. Du kannst den ursprünglichen String aber nicht mehr wiederherstellen. Wenn Passwörter nicht gehasht werden und die Datenbank in falsche Hände gerät, sind alle Benutzerkonten kompromittiert. Einige Benutzer werden das selbe Passwort auch bei anderen Diensten verwenden. Darum ist es wichtig, Sicherheit ernst zu nehmen.

Passwörter mit password_hash hashen

Mit PHP 5.5 wird die Funktion password_hash eingeführt. Zur Zeit verwendet sie BCrypt, den stärksten aktuell von PHP unterstützten Algorithmus. Zukünftig wird sie aktualisiert werden, um bei Bedarf weitere Algorithmen zu unterstützen. Die Bibliothek password_compat wurde geschaffen, um mit PHP >= 5.3.7 vorwärtskompatibel zu sein.

Unten hashen wir einen String und prüfen anschließend gegen einen neuen String. Wie die beiden Strings unterschiedlich sind (‘secret-password’ gegen ‘bad-password’), wird diese Anmeldung scheitern.

<?php
require 'password.php';

$passwordHash = password_hash('secret-password', PASSWORD_DEFAULT);

if (password_verify('bad-password', $passwordHash)) {
    //Correct Password
} else {
    //Wrong password
}

Daten filtern

Vertraue niemals (niemals!) Eingaben in deinen PHP-Code von außen. Bereinige und validiere externe Eingaben, bevor du sie in deinem Code verwendest. Die Funktionen filter_var und filter_input können Text bereinigen und Textformate wie zum Beispiel E-Mail-Adressen validieren.

Eine Eingabe von außen kann alles mögliche sein: Formulareingaben über $_GET und $_POST, einige Werte im Superglobal $_SERVER und der Inhalt des HTTP-Requests über fopen('php://input', 'r'). Denke daran: Fremdeingaben sind nicht beschränkt auf Formulardaten, die ein Benutzer absendet. Hochgeladene und heruntergeladene Dateien, Sessionwerte, Daten aus Cookies und Daten von dritter Seite wie Webservices sind auch Fremdeingaben.

Während Fremdeingaben gespeichert, kombiniert und später verwendet werden können, bleiben sie noch immer Fremdeingaben. Frage dich jedes Mal, ob die Daten korrekt gefiltert sind, wenn du sie in deinem Code verarbeitest, ausgibst, verbindest oder einbaust.

Daten können - abhängig von der Verwendung - unterschiedlich gefiltert werden. Werden ungefilterte Fremdeingaben in die HTML-Seite eingeschleust, kann HTML und JavaScript auf deiner Site ausgeführt werden. Das nennt man Cross-Site Scripting (XSS), eine sehr gefährliche Angriffsmethode. Eine Methode, um XSS zu vermeiden, ist, alle vom Benutzer erzeugten Daten vor der Ausgabe zu bereinigen. Dazu kannst du entweder alle HTML-Tags mit der Funktion strip_tags entfernen oder Zeichen mit spezieller Bedeutung mit Hilfe der Funktionen htmlentities oder htmlspecialchars in die entsprechenden HTML-Entitäten umwandeln.

Ein weiteres Beispiel ist die unerwünschte Weitergabe von Optionen an die Ausführung über die Befehlszeile. Das kann extrem gefährlich sein und ist ganz allgemein eine schlechte Idee. Du kannst die eingebaute Funktion escapeshellarg verwenden, um die Argumente des ausgeführten Befehls zu bereinigen.

Ein letztes Beispiel ist die Verwendung von Fremdeingaben zur Bestimmung einer Datei, die vom Dateisystem geladen wird. Das kann ausgenutzt werden, um an Stelle eines Dateinamens einen Dateipfad zu erreichen. Du musst “/”, “../”, Null-Bytes und andere Zeichen aus dem Dateipfad entfernen, damit nicht versteckte, private und heikle Dateien geladen werden.

Bereinigung

Mit der Bereinigung entfernt oder entschärft man illegale oder unsichere Zeichen aus Fremdeingaben.

Zum Beispiel solltest du Fremdeingaben bereinigen, bevor du die Eingabe in HTML einbaust oder sie in einer SQL-Abfrage verwendest. Wenn du gebundene Parameter mit PDO verwendest, wird PDO die Eingaben für dich bereinigen.

Manchmal ist es nötig, einige sichere HTML-Tags in der Eingabe zu erlauben. Das ist sehr schwierig und wird oft vermieden. Als Ausweichlösung werden Markdown, Textile oder BBCode verwendet, obwohl Whitelisting-Bibliotheken wie HTML Purifier aus diesem Grund existieren.

Siehe Filter zur Bereinigung

Validierung

Validierung stellt sicher, dass Fremdeingaben den Erwartungen entsprechen. Zum Beispiel kannst du eine E-Mail-Adresse, eine Telefonnummer oder eine Altersangabe validieren, wenn du eine Registrierungsanmeldung verarbeitest.

Siehe Filter zur Validierung

Konfigurationsdateien

Wenn du Konfigurationsdateien erstellst, empfiehlt sich als beste Vorgehensweise eine der folgenden Methoden:

Register Globals

ACHTUNG: Seit PHP 5.4.0 wurde die Einstellung register_globals entfernt. Sie kann nicht mehr eingesetzt werden. Dieser Abschnitt ist nur als Warnung für jene gedacht, die eine alte Anwendung aktualisieren wollen.

Die Konfigurationseinstellung register_globals macht einige Typen von Variablen (inklusive denen aus $_POST, $_GET und $_REQUEST) im globalen Sichtbarkeitsbereich benutzbar. Das kann schnell zu Sicherheitsproblemen führen, da die Anwendung die Herkunft der Daten nicht mehr effektiv verfolgen kann.

Zum Beispiel: $_GET['foo'] würde über $foo erreichbar und könnte so Variablen überschreiben, die nicht deklariert wurden. Wenn du PHP < 5.4.0 einsetzt, stelle sicher, dass register_globals off ist.

Fehlermeldungen

Das Aufzeichnen von Fehlern kann helfen, Problembereiche in deiner Anwendung zu finden, es kann aber auch Informationen über die Struktur deiner Anwendung gegenüber der breiten Allgemeinheit enthüllen. Um deine Anwendung effektiv vor Problemen zu schützen, die durch die Ausgabe diese Meldungen entstehen könnten, musst du deinen Produktivserver anders konfigurieren als deinen Entwicklungsserver.

Entwicklung

Um jeden möglichen Fehler während der Entwicklung anzuzeigen, konfiguriere folgende Einstellung in deiner php.ini:

display_errors = On
display_startup_errors = On
error_reporting = -1
log_errors = On

Mit dem Wert -1 wird jeder mögliche Fehler auch in zukünftigen Versionen von PHP angezeigt. Die Konstante E_ALL verhält sich seit PHP 5.4 auch so. - php.net

Der Errorlevel E_STRICT wurde mit PHP 5.3.0 eingeführt und ist nicht Teil von E_ALL, wurde aber Teil von E_ALL in 5.4.0. Was bedeutet das? In Bezug auf Fehlermeldungen musst du in Verion 5.3 entweder -1 oder E_ALL | E_STRICT verwenden.

Jeden Fehler melden ja nach PHP-Version

Produktion

Um keinen Fehler im Produktivsystem anzuzeigen, konfiguriere folgende Einstellung in deiner php.ini:

display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL
log_errors = On

Mit diesen Einstellungen im Produktivsystem werden Fehler immer noch in den Error Logs des Webservers eingetragen, aber dem Benutzer nicht angezeigt. Weitere Informationen zu diesen Einstellungen findest du im PHP-Handbuch:

Zurück zum Start

Testen

Als bestes Verfahren gilt das Schreiben von automatisierten Test für deinen PHP-Code, das zu gut konstruierten Anwendungen führen kann. Automatisierte Tests sind ein großartiges Werkzeug, um sicherzustellen, dass deine Anwendung nicht nach Änderungen oder Erweiterungen versagt. Sie sollten nicht ignoriert werden.

Es gibt mehrere verschiedenen Typen von Testwerkzeugen oder Frameworks für PHP, die unterschiedliche Heransgehensweisen einsetzen - alle versuchen aber, manuelle Test und große Qualitätssicherungsteams nur zum Zweck der Fehlerfindung nach Änderungen zu vermeiden.

Testgetriebene Entwicklung

Aus Wikipedia:

Test-driven development (TDD) is a software development process that relies on the repetition of a very short development cycle: first the developer writes a failing automated test case that defines a desired improvement or new function, then produces code to pass that test and finally refactors the new code to acceptable standards. Kent Beck, who is credited with having developed or ‘rediscovered’ the technique, stated in 2003 that TDD encourages simple designs and inspires confidence

Du kannst diene Anwendung auf verschiedene Arten testen.

Unit-Tests

Unit-Tests sind ein Entwicklungsansatz, der sicherstellt, dass Funktionen, Klassen und Methoden wie erwartet arbeiten von Beginn der Entwicklung über den ganzen Entwicklungszyklus. Durch die Überprüfung von Werten, die als Ein- und Ausgabe von Funktionen und Methoden fungieren, kannst du die Korrektheit der inneren Logik sicherstellen. Über Dependency Injection, “Attrappen”-Klassen und Funktionsstummel kannst du die Testabdeckung erhöhen und verifizieren, dass Abhängigkeiten korrekt verwendet werden.

Beim Bau einer Klasse oder Funktion solltest du einen Unit-Test für jedes Verhalten schaffen. Zumindest solltest du sicherstellen, dass bei ungültigen Eingabewerten Fehler passieren und die Funktion bei gültigen Argumenten funktioniert. Damit ist sichergestellt, dass alte Funktionalität erhalten bleibt, wenn du diese Klasse später änderst. Die einzige Alternative wäre var_dump() in einer test.php, und so baut man keine Anwendung - ob klein oder groß.

Die andere Anwendung für Unit-Tests ist als Beitrag in einem Open Source Projekt. Wenn du einen Unit-Test schreiben kannst, der zeigt, dass eine Funktionalität fehlerhaft ist und das dann mit durchlaufendem Testergebnis korrigierst, werden Patches wahrscheinlicher akzeptiert. Wenn du ein Projekt betreibst, das Pull Requests akzeptiert, solltest du das als Erfordernis empfehlen.

PHPUnit ist das De-Facto Testframework zum Erstellen von Unit-Tests für PHP, aber es gibt einige Alternativen:

Integrationstests

Aus Wikipedia:

Integration testing (sometimes called Integration and Testing, abbreviated “I&T”) is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.

Viele der gleichen Werkzeuge für Unit-Tests können auch für Integrationstests verwendet werden, da dieselben Prinzipien verwendet werden.

Funktionaler Test

Funktionale Test oder Akzeptanztest bestehen aus Werkzeugen, mit denen automatisierte Tests erstellt werden können, die deine Anwendung tatsächlich benutzen, anstatt nur das korrekte Verhalten einzelner Codeeinheiten und deren Verständigung untereinander zu verifizieren. Diese Werkzeuge arbeiten typischerweise mit Echtdaten und simulieren tatsächliche Anwender der Applikation.

Funktionale Testwerkzeuge

Verhaltensgetriebe Entwicklung

Es gibt zwei Arten verhaltensgetriebener Entwicklung (Behavior-Driven Development, BDD): SpecBDD und StoryBDD. SpecBDD konzentriert sich auf das technische Verhalten oder Code, während sich StoryBDD auf Geschäfts- oder Eigenschaftenverhalten oder Interaktionen fokussiert. Es gibt Framework für beiden Typen in PHP.

Für StoryBDD schreibt man menschenlesbare Geschichten, die das Verhalten deiner Anwendung beschreiben. Diese Geschichten können als tatsächliche Tests für deine Anwendung geprüft werden. Als Framework für StoryBDD in PHP wird Behat verwendet, das von Rubys Cucumber inspiriert wurde und das Gherkin als DSL zur Beschreibung des Eigenschaftsverhaltens implementiert.

Für SpecBDD schreibst du Spezifikationen, die beschreiben, wie sich dein tatsächlicher Code verhalten soll. Statt eine Funktion oder Methode zu testen wird beschrieben, wie sich diese Funktion oder Methode verhalten soll. PHP bietet für diesen Zweck das Framework PHPSpec, das von RSpec project für Ruby inspiriert wurde.

Ergänzende Textwerkzeuge

Neben individuellen Tests und verhaltensgetriebenen Frameworks gibt es auch eine Anzahl von generischen Frameworks und Hilfsbibliotheken, die für jeden bevorzugten Zugang nützlich sind.

Werkzeuge

Zurück zum Start

Server und Ausrollung

PHP-Anwendungen können auf verschiedene Arten auf Server ausgerollt und betrieben werden.

Platform as a Service (PaaS)

PaaS stellt das System und die Netzwerkarchitektur für PHP-Anwendungen im Web bereit. Das bedeutet keine oder geringe Konfiguration zum Start von PHP-Anwendungen oder PHP-Frameworks.

In letzter Zeit wurde PaaS zu einer beliebten Methode für die Ausrollung, das Hosting und die Skalierung von PHP-Anwendungen aller Größen. Du kannst eine Liste von Anbietern für PHP-PaaS “Platform as a Service” in unserem Abschnitt Ressourcen finden.

Virtuelle oder dedizierte Server

Wenn du mit der Systemadministration vertraut bist oder ein Interesse hast, das zu lernen, erhältst du bei virtuellen oder dedizierten Servern die volle Kontrolle über die Produktivumgebung deiner Anwendung.

nginx und PHP-FPM

Über den eingebauten FastCGI Process Manager (FPM) passt PHP sehr gut zu nginx, einem schlanken leistungsstarken Webserver. Nginx benötigt weniger Speicher als Apache und kann mehr gleichzeitige Zugriffe besser bearbeiten. Das ist speziell bei virtuellen Servern mit wenig Speicher wichtig.

Apache und PHP

PHP und Apache haben eine lange gemeinsame Geschichte. Apache ist flexibel konfigurierbar und besitzt viele Module zur Funktionserweiterung. Apache ist eine beliebte Wahl für billiges Shared Hosting und eine einfache Basis für PHP-Frameworks und Open-Source-Anwendungen wie Textpattern CMS. Unglücklicherweise benötigt Apache mehr Ressourcen als nginx und kann nicht so viele Besucher gleichzeitig bedienen.

Apache hat einige Möglichkeiten, um PHP zu starten. Die geläufigste und einfachste ist das Prefork MPM mit mod_php5. Zwar ist es nicht die effizienteste, aber die einfachste Methode der Installation und des Betriebs. Es ist wahrscheinlich die beste Wahl wenn du nicht zu tief in die Serveradministration einsteigen möchtest. Beachte, dass mod_php das Prefork MPM erfordert.

Alternativ kannst du für mehr Leistung und Stabilität dasselbe FPM-System wie nginx einsetzen und das Worker MPM oder das Event MPM mit mod_fastcgi oder mod_fcgid verwenden. Diese Konfiguration wird signifikant effizienter mit dem Speicher umgehen und schneller sein, aber mehr Arbeit bei der Installation machen.

Shared Hosting

PHP verdankt Shared Hosting seine Popularität. Man findet kaum einen Host ohne installiertes PHP, aber achte darauf, dass es die aktuelle Version ist.

Bei Shared Hosting starten du und andere Entwickler ihre Anwendungen auf einer einzigen Maschine. Der Vorteil ist, dass Shared Hosting zu einer billigen Massenware wurde. Der Nachteil ist, dass du nie weißt, welche Art von Krawall deine Mitbewohner anrichten; Überlast auf dem Server oder offenen Sicherheitslücken sind die Hauptargumente gegen Shared Hosting. Wenn es dein Budget erlaubt, solltest du Shared Hosting meiden.

Baue und verteile deine Anwendung

Wenn du das Datenbankschema manuell änderst oder deine Tests manuell startest, bevor du deine Dateien (manuell) aktualisierst, denke noch mal nach! Mit jeder manuellen Aufgabe, die man für die Ausrollung einer neuen Version deiner Anwendung benötigt, steigen die Chancen für potentiell fatale Fehler. Ob es um ein einfaches Update, einen umfassenden Build-Prozess oder sogar um eine kontinuierliche Integrationsstrategie geht, Build-Automation ist dein Freund.

Unter den Aufgaben, die du automatisieren kannst, sind etwa:

Werkzeuge für die Build Automation

Build-Werkzeuge kann man als Sammlung von Scripts beschreiben, die übliche Aufgaben der Softwareentwicklung bearbeiten. Das Build-Werkzeug ist nicht Teil deiner Software, sonder es wirkt “von außen”.

Es gibt viele Open-Source-Werkzeuge, die dir bei der Build Automation helfen. Manche davon sind in PHP geschrieben, andre nicht. Das solte dich nicht von ihrem Einsatz abhalten, wenn sie besser für einen bestimmten Job geeignet sind. Hier sind ein paar Beispiele:

Phing ist der einfachste Weg, mit automatisierter Ausrollung in der PHP-Welt zu beginnen. Mit Phing kannst du das Verpacken, Ausrollen oder Testen von einer einfachen XML-Datei aus steuern. Phing, das auf Apache Ant basiert, bietet eine umfangreiche Menge von Aufgaben, die üblicherweise benötigt werden, um Webanwendungen zu installieren oder zu aktualisieren, und kann mit zusätzlichen in PHP geschriebenen Aufgaben erweitert werden.

Capistrano ist ein System für Programmierer mit mittleren oder fortgeschrittenen Kenntnissen, um Befehle in einer strukturierten, wiederholbaren Art und Weise auf einer oder mehrerer Maschinen durchzuführen. Es ist für die Ausrollung von Anwendungen in Ruby on Rails vorkonfiguriert, es werden aber auch erfolgreich PHP-Systeme damit ausgerollt. Der erfolgreiche Einsatz von Capistrano hängt von brauchbaren Kenntnissen in Ruby und Rake ab.

Dave Gardners Blogbeitrag PHP Deployment with Capistrano ist ein guter Startpunkt für PHP-Programmierer, die sich für Capistrano interessieren.

Chef ist mehr als ein Framework für das Ausrollen - ein sehr mächtiges Integrationsframework auf Ruby-Basis, das deine Anwendung nicht nur ausrollt, sondern den gesamten Server oder virtuelle Maschinen baut.

Ressourcen zu Chef für PHP-Entwickler:

Weiterführende Literatur:

Kontinuierliche Integration

Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily — leading to multiple integrations per day. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly.

– Martin Fowler

Es gibt verschiedene Arten, um kontinuierliche Integration für PHP zu implementieren. In letzter Zeit hat Travis CI einen großen Beitrag dazu geleistet, kontinuierliche Integration auch für kleine Projekte Realität werden zu lassen. Travis CI ist eine gehostete Lösung für die Open-Source-Community. Es ist in Github integriert und bietet erstklassige Unterstützung für viele Sprachen inklusive PHP.

Weiterführende Literatur:

Zurück zum Start

Caching

PHP ist von Haus aus schnell, aber Flaschenhälse können entstehen, wenn du Verbindungen über weite Strecken aufbaust, Dateien lädst, etc. Zum Glück gibt es verschiedene Werkzeuge, die gewisse Teile deiner Anwendung beschleunigen oder die Häufigkeit dieser zeitintensiven Aufgaben reduzieren.

Bytecode-Cache

Wenn eine PHP-Datei ausgeführt wird, wird sie im Hintergrund zuerst in Bytecode (auch Opcode genannt) kompiliert und dieser Bytecode anschließend ausgeführt. Solange die PHP-Datei nicht verändert wurde, bleibt dieser Bytecode gleich. Das heißt, dass der Kompilierungsschritt eine Verschwendung von CPU-Ressourcen ist.

Hier kommt der Bytecode-Cache ins Spiel. Er verhindert die redundante Kompilierung durch das Speichern von Bytecode im Hauptspeicher und ermöglicht die Wiederverwendung bei nachfolgenden Aufrufen. Der Bytecode-Cache ist innerhalb weniger Minuten einzurichten und wird deine Anwendung signifikant beschleunigen. Es gibt wirklich keinen Grund, ihn nicht einzusetzen.

Beliebte Bytecode-Caches sind:

Objektcache

Manchmal ist es vorteilhaft, einzelne Objekte in deinem Code zu cachen wie etwa Daten, die nur mit hohem Aufwand zu erhalten sind, oder Datenbankzugriffe, deren Ergebnis sich wahrscheinlich nicht ändert. Du kannst Objektcache-Software verwenden, um diese Teile von Daten im Speicher zu halten und extrem schnell später darauf zuzugreifen. Wenn du diese Elemente in einem Datenspeicher sicherst, nachdem du sie abgerufen hast, und anschließend für nachfolgende Anfragen direkt aus dem Cache holst, kannst du wesentliche Geschwindigkeitsverbesserungen erreichen und die Last der Datenbankserver vermindern.

Viele beliebte Lösungen für Bytecode-Caches erlauben dir auch, eigene Daten zu cachen, was noch ein zusätzlicher Grund ist, diese zu deinem Vorteil zu nutzen. APC, XCache und WinCache bieten APIs, um Daten aus deinem PHP-Code in ihren Cachespeicher zu sichern.

Die meist verbreiteten Systeme für speicherbasierende Objektcaches sind APC und memcached. APC ist eine exzellente Wahl für Objektcaches; es beinhaltet ein einfaches API, das an den Server gebunden ist, auf dem es installiert ist. Memcached andererseits wird als getrennter Dienst installiert und kann über das Netzwerk angesprochen werden; das bedeutet, dass du Objekte in einem schnellen Datenspeicher ablegen und von vielen verschiedenen Systemen abrufen kannst.

Beachte: Wenn PHP als (Fast-)CGI-Anwendung deines Webserver läuft, besitzt jeder PHP-Prozess seinen eigenen Cache. Das heißt, dass die APC-Daten nicht zwischen den Arbeitsprozessen geteilt werden. In diesen Fällen könnte man den Einsatz von memcached überlegen, da dieser nicht an PHP-Prozesse gebunden ist.

In einer Netzwerk-Konfiguration wird APC im Regelfall schneller sein als memcached, während memcached weiter und schneller skaliert. Wen du nicht planst, deine Anwendung auf mehrere Server zu verteilen oder die zusätzlichen Eigenschaften von memcached nicht benötigst, ist APC wahrscheinlich die beste Wahl als Objektcache.

Beispiellogik für APC:

<?php
// check if there is data saved as 'expensive_data' in cache
$data = apc_fetch('expensive_data');
if ($data === false) {
    // data is not in cache; save result of expensive call for later use
    apc_add('expensive_data', $data = get_expensive_data());
}

print_r($data);

Mehr über populäre Objektcaching-Systeme:

Zurück zum Start

Ressourcen

Von der Quelle

Folgenswerte Menschen

Beratung

Anbieter für PHP PaaS

Frameworks

Viele PHP-Entwickler verwenden Frameworks beim Bau von Webanwendungen, statt das Rad neu zu erfinden. Frameworks abstrahieren viele der grundlegenden Anliegen und bieten hilfreiche, einfach verwendbare Schnittstellen, um übliche Aufgaben zu erfüllen.

Du brauchst nicht für jedes Projekt ein Framework. Manchmal ist gewöhnliches PHP die richtige Art der Lösung, aber wenn du ein Framework benötigst, dann findest du drei typische Arten:

Micro-Frameworks sind im wesentlichen eine Hülle, um einen HTTP-Request möglichst schnell an einen Callback, einen Controller oder eine Methode weiterzuleiten, und werden manchmal von Bibliotheken wie etwa Datenbankhüllen und Ähnlichem begleitet. Sie werden typischerweise eingesetzt, um Remote-HTTP-Dienste zu bauen.

Viele Frameworks fügen eine beträchtliche Anzahl von Fähigkeiten zu dem hinzu, was ein Micro-Framework bietet. Diese nennt man “Vollständige Frameworks”. Sie enthalten oft ORMs, Pakte zur Authentifizierung etc.

Komponentenbasierende Frameworks sind Sammlungen von spezialisierten Bibliotheken für einen genau definierten Zweck. Verschiedene komponentenbasierende Frameworks können miteinander eingesetzt werden, um ein Micro- oder vollständiges Framework zu bilden.

Komponenten

Wie bereits erwähnt sind “Komponenten” ein weiterer Ansatz, um mehrfach verwendbaren Code zu erstellen, zu verteilen und zu implementieren. Es gibt mehrere Komponentenverzeichnisse, von denen die wichtigsten diese sind:

Diese beiden Verzeichnisse haben zugehörige Werkzeuge für die Befehlszeile, um beim Installations- und Aktualisierungsvorgang zu helfen, und wurden detaillierter im Abschnitt Verwaltung von Abhängigkeiten behandelt.

Es gibt auch komponentenbasierte Frameworks, die den Einsatz ihrer Komponenten mit minimalem oder keinen Voraussetzungen erlauben. Zum Beispiel kannst du das Paket FuelPHP Validation unabhängig vom gesamtem Framework FuelPHP einsetzen. Diese Projekte sind im Wesentlichen nur ein weiteres Verzeichnis von wiederverwendbaren Komponenten:

Zurück zum Start

Community

Die PHP-Community ist so vielfältig wie zahlreich, und ihre Mitglieder unterstützen Anfänger gerne. Vieleicht möchtest du einer örtlichen PHP-Anwendergruppe (PHP User Group, PUG) beitreten oder größere PHP-Konferenzen besuchen, um mehr über die besten Methoden zu lernen, die hier gezeigt werden. Du kannst dich mit Gleichgesinnten im Channel #phpc auf irc.freenode.com über IRC treffen oder @phpc auf Twitter folgen. Gehe raus, triff neue Entwickler, lernen neue Themen und schließe neue Freundschaften. Weitere Community-Ressourcen sind die Community der PHP-Entwickler auf Google+ und StackOverflow.

Lies den offiziellen PHP-Events-Kalendar

PHP-Anwendergruppen

Wenn du in einer größeren Stadt lebst, bestehen gute Chancen, dass es eine PHP-Anwendergruppe in der Nähe gibt. Obwohl es keien offizeille Liste der PHP-Anwendergruppen, kannst du die nächstgelegene PHP-Anwendergruppe einfach über eine Suche bei Google oder Meetup.com finden. Wenn du in einer kleineren Stadt lebst, gibt es vielleicht noch keine lokale PUG; wenn das so ist, gründe eine!

Mehr über Anwendergruppen im PHP-Wiki

PHP-Konferenzen

Die PHP-Community veranstaltet auch größere regionale und nationale Konferenzen in vielen Ländern rund um die Welt. Bekannte Mitglieder der PHP-Community halten oft Vorträge auf diesen größeren Veranstaltungen, so dass diese eine großartige Möglichkeit sind, direkt von führenden Köpfen zu lernen.

Finde eine PHP-Konferenz

Zurück zum Start