PHP 7 ist 30-70% schneller als PHP 5.6 und braucht nur selten eine Anpassung am Code. Die nachfolgende Anleitung ist für Debian 8 ‚Jessie‘ geschrieben, wir installieren PHP 7 neben PHP 5 und können jederzeit hin-und-her wechseln.

Ich habe erfolgreich WordPress 4.6, Drupal 6, Xenforo 1.5.8, Nextcloud 9.0.53 und DokuWiki mit PHP 7.0.10 am laufen – fast problemlos. Nur ein einzelnes, wichtiges WordPress-Plugin war in meinem Fall noch nicht PHP7-fähig: W3 Total Cache. Aber auch dafür gibt es eine gute Lösung in Form eines Forks, mehr dazu nach der Installationsanleitung.

Administratoren welche ihr PHP nicht mit libapache2-mod-php, sondern mit FastCGI oder mod-fpm in Apache eingebunden haben, denen muss ich jetzt nicht wirklich erklären wie man PHP 7 installiert – die wissen wie das geht.

Meine Anleitung zielt ab auf libapache2-mod-php, das ist der Standard unter Debian mit Apache. Damit können wir PHP 5 und PHP 7 zwar nicht gleichzeitig laufen lassen, aber durchaus parallel installieren und je nach Bedarf hin-und-her schalten zwischen den beiden Versionen.

Optional: phpinfo() Datei anlegen

Um während der Installation sofort prüfen zu können welche PHP-Version gerade läuft, erstellen wir im Web-Verzeichnis neben der index.php eine Datei phpinfo.php und befüllen sie mit folgendem Code:

<?php
phpinfo();
?>

Danach öffnen wir das File unter www.meineseite.de/phpinfo.php und sehen, dass derzeit eine PHP 5.6 Version aktiv ist. Das ist nämlich die mitgelieferte Version von Debian 8 ‚Jessie‘.

Debian 8 ‚Jessie‘: PHP7 neben PHP5 installieren

PHP 7 ist im zusätzlichen Repository „Dotdeb“ für Debian 8 verfügbar. Als erstes fügen wir das Repository hinzu:

#dotdeb Repository hinzufügen:
echo 'deb http://packages.dotdeb.org jessie all' > /etc/apt/sources.list.d/dotdeb.list

#dotdeb Repository Key hinzufügen:
curl http://www.dotdeb.org/dotdeb.gpg | apt-key add -

#apt update ausführen
apt-get update

Die Paketnamen sind anders als diejenigen von PHP 5, weshalb das installierte PHP 5 unangetastet vorhanden und aktiviert bleibt. Wichtig dabei: Man sollte mit dpkg --get-selections nachschauen, welche PHP 5-Pakete denn schon installiert sind, um die Pendants derselben als PHP 7-Pakete zu installieren.

#Installierte PHP5 Pakete anschauen
dpkg --get-selections | grep php5

#Die gleichnamigen PHP7-Pakete installieren
#In meinem Fall habe ich eine Reihe an Paketen hinzugefügt:
apt-get install php7.0 libapache2-mod-php7.0 php7.0-apcu php7.0-curl php7.0-xml php7.0-zip php7.0-mbstring php7.0-gd php7.0-mysql

Diese Installation wird noch rein gar nichts an der aktivierten PHP 5-Installation verändern oder deaktivieren, apt-get install darf in keinem Fall ein Paket als „wird gelöscht“ markieren. Der eigene Webserver läuft weiterhin mit PHP 5, wir refreshen www.meineseite.de/phpinfo.php und überprüfen das gleich mal 🙂
PHP 7 muss erst noch aktiviert werden.

Hinweis: Noch bevor PHP 7 aktiviert wird, kann jetzt die neue Config-Datei /etc/php/7.0/apache2/php.ini angepasst werden. Vermutlich hat man nämlich in der alten PHP 5 Config /etc/php5/apache2/php.ini früher einmal Änderungen gemacht, zum Beispiel einen höheren Wert bei memory_limit gesetzt.

PHP 7 aktivieren, PHP 5 deaktivieren

Jetzt wird es ernst. Mit den folgenden Befehlen deaktivieren wir PHP 5, aktivieren PHP 7 und besiegeln die Veränderung durch den Apache-Restart.

a2dismod php5
a2enmod php7.0
service apache2 restart

Warnung: Das dümmste was man machen kann ist, den Apache neustarten bevor php7.0 enabled wurde. Dann wäre nämlich kein PHP aktiviert und der Apache liefert die .php Datei als Download zurück…. Da drin stehen Passwörter! Also, immer nach a2dismod zwingend eine PHP-Version a2enmod php7.0 oder a2enmod php5 enablen, bevor der Apache durchgestartet wird.

Zuerst überprüfen wir mit F5 Refresh www.meineseite.de/phpinfo.php ob die Umstellung geklappt hat.

Als nächstes rufen wir unsere Webseite(n) auf. Es ist möglich, dass die Webseite einfach „weiß“ bleibt, dann wirft PHP im Errorlog die Ursache aus aber verbirgt den Fehler dem Besucher gegenüber. In diesem Fehler-Fall schalten wir sofort wieder auf PHP 5 zurück:

a2dismod php7.0
a2enmod php5
service apache2 restart

Damit hatten wir eine Downtime von vielleicht 10 Sekunden – das dürfte noch zu verkraften sein. Nun kann in aller Seelenruhe die Fehlerursache im Errorlog nachgeschaut werden, bei Debian 8 ‚Jessie‘ in /var/log/apache2/ zu finden. Ich empfehle den Ordner nach den neusten Logdateien zu sortieren ls -rtlha /var/log/apache2 und das entsprechende Errorlog zu begutachten.

Im übrigen lege ich einem jeden Administrator ans Herzen die nächsten Tage das Errorlog immer mal wieder aufzusuchen, vielleicht gab es über die Zeit weitere Fehler von neuen Besuchern auf irgendwelchen Unterseiten. Die Chance dazu ist aber gering 🙂

Errorlog: Probleme mit PHP 7 identifizieren

Das Apache-Errorlog wird die Ursache anzeigen, weshalb PHP 7 Probleme machte. In meinem Fall funktionierte das beliebte WordPress-Plugin W3 Total Cache nicht (die Webseite blieb einfach weiß), denn es benutzt die nicht mehr verfügbare Funktion mysql_connect() anstelle mysqli oder PDO. So etwas kann man als nicht-Programmierer nur schwer beeinflussen, man sollte sofort ein Support-Thread beim Plugin-Hersteller auf WordPress.org einstellen und auf einen Patch hoffen.

Manchmal deutet der Fehler aber auch nur auf ein fehlendes PHP 7-Paket hin. Ein Errorlog-Eintrag wie „could not run xml (blabla)“ könnte darauf hindeuten, dass php7.0-xml nicht installiert wurde. Mit apt-cache search php7 kann man sich alle installierbaren Extension-Pakete anzeigen lassen. Einfach nachinstallieren und PHP 7 nochmal aktivieren. So einfach 🙂

Bezüglich W3 Total Cache unter PHP 7 gibt es eine Lösung: Man muss einen Fork benutzen der um ganz viele Fehler erleichtert wurde und auch PHP 7-fähig ist, denn die Original-Version wird leider nicht mehr genügend aktualisiert. Nachzulesen hier.

Benchmark PHP 7.0 vs PHP 5.6

Das hin-und-her schalten zwischen PHP 7 und PHP 5 erlaubt mir einfache Geschwindigkeitstests durchzuführen. Ich habe lediglich ein paar Quick-Tests mit tools.pingdom.com gemacht, schon diese Tests zeigen einen großen Sprung bei der Ladegeschwindigkeit:

  • PHP 5: 1.90 – 2.25 Sek (games4linux.de Startseite)
  • PHP 7: 1.43 – 1.53 Sek (games4linux.de Startseite)
    • Das ist bis zu 36,5% schneller!

Ein Leistungsgewinn mit vergleichsweise wenig Aufwand, so hat sich die Migration auf PHP 7 gelohnt wie ich finde.

Viel Spass mit PHP 7!

PS: Nicht vergessen die phpinfo.php Datei wieder zu löschen 🙂

Nachtrag: Upgrade-Gedanken

Dank installiertem PHP 7 wird apt-get upgrade in Zukunft deutlich öfters neue PHP-Versionen mit sich bringen. Während ich diese Zeilen schreibe ist PHP 7.0.10 die aktuellste, stabile Version (während PHP 7.1.0 schon in den Startlöchern steht).

Mit PHP 7 ändert sich leider deutlich öfters als noch mit PHP 5.6 der Inhalt von php.ini weshalb apt-get install nachfragen wird, ob die aktuelle php.ini jeweils überschrieben werden soll. Verweigerer werden unweigerlich ein Probem bekommen: Wenn man zu oft wählt keep the current local version installed ist die eigene php.ini irgendwann zu „alt“. Man sollte sich unbedingt schon vorher (jetzt!) aufschreiben, welche händischen Änderungen in der php.ini gemacht wurden und von Zeit-zu-Zeit mittels apt-get upgrade die PHP 7 php.ini aktualisieren überschreiben lassen, um daraufhin die früheren Anpassungen wieder einzufügen.

Das ist den Tribut den man bezahlt, wenn der eigene Server den „neusten heißen Scheiß“ haben soll 😀

  • Peter Lustig

    Danke, hat mir sehr geholfen. Ich habe es auf 2 Servern probiert. Auf einem der Server kam beim Ausführen von „a2enmod php7.0“ der Fehler „ERROR: Module php7.0 does not exist!“. Habe dann aber noch zusätzlich das Paket libapache2-mod-php7.0 installiert (apt-get install libapache2-mod-php7.0). Anschließend hat alles funktioniert.

    • Schroeffu

      Hallo Peter, danke für dein Feedback. In meinem Fall hat apt automatisch libapache2-mod-php7.0 dazu installiert, aber ich sollte nicht davon ausgehen dass das auf anderen Servern auch der Fall ist. Ich werde das Paket in die Anleitung mit aufnehmen. Thanks again für deine Rückmeldung!

  • Axel Birndt

    Hi,

    Danke für Deine Anleitung. Ich habe mal Deine Anleitung zum Anlass genommen das bei mir mal auszuprobieren.
    Auf meiner Seite http://www.2axels-company.de/blog/2016/09/09/debian-8-0-jessie-php-7-0-installieren/ habe ich auch einen Teil Deiner Anleitung übernommen und noch meine Problemchen ergänzt.
    Ansonsten hat aber alles prima funktioniert. Vielen Dank für Deine Mühe!
    Gruß Axel

  • Omar Khalil

    Thank you so much for providing the steps, although my German is not so good, but i good understand the procedures, i spend many hours yesterday building PHP 7.0.11 and failing, but now i don’t need building as you have give us the wonderful repo with the lastest PHP!!!!

    thanks a lot again.

    • Schroeffu

      Omar you are welcome 🙂 Sorry that it is only in german, good to see that be general instruction is understand-able in english 🙂
      Have fun with php7!

      Schroeffu

  • Ioannis

    Vielen Dank!
    Hat mir sehr weiter geholfen, ich habe mir bereits andere Tutorials angeguckt, die aber leider trotz meiner langjährigen Linux Erfahrung zu keinem Ergebnis geführt haben. Weiter so, habe mir den Blog eingespeichert und werde ab&an vorbeischauen. 🙂

  • Christian Ackerman

    Kannst du evt. auch noch eine Anleitung für einen aktuellen Apache erstellen. Ich würde z.B. mal HTTP2 ausprobieren. Dafür ist der Apache aus den Standard Paketquellen aber zu alt.

    Das wäre echt toll.

    • Schroeffu

      Spannend, dass du das gerade jetzt fragst. Heute morgen habe ich kurz nachgeschaut ab wann HTTP/2 mit dem Apache2 läuft (hatte zu kämpfen mit Performance Problemen, lag aber letztlich an Javascript), ja genau Debian 8 hat noch 2.4.10 dabei. Soll ab 2.4.17 inklusive sein.

      Ich persönlich plane einen Server-Umzug, die Webseiten dort möchte ich direkt mit Nginx laufen lassen ohne Apache, auch nicht dahinter als Backend. Bei Nginx ist HTTP/2 „fast schon Standard“, übertrieben gesagt 🙂 Daher ist es eher unwahrscheinlich dass ich über Apache2<>HTTP/2 schreibe, sorry.