PHP 7 ist da
Glen Langer
Contao Camp 2016 in Nürnberg
Version: 1.3.0 vom 20.07.2017
(Bild: PHP.net)
Über mich
- Contao seit 2.5.8
- PHP ZCE
- Forum: BugBuster
- Camp: James Buster, im Auftrag von Contao
- http://contao.ninja/
Inhalt
- Umstieg, wann und warum?
- Neue, zu alte und fast zu alte Funktionen
- Inkompatibilitäten
- Migrationshinweise,
speziell für Contao Erweiterungen - Tools
Umstieg, wann und warum?
http://php.net/supported-versions.php
PHP 7.1 wurde am 02.12.2016 veröffentlicht
Umstieg, wann und warum?
Aus Performance Gründen!
Kern von PHP grundlegend überarbeitet, gegenüber PHP 5.0 soll PHP 7.0 ganze 10-14 mal schneller sein, gegenüber PHP 5.6 immerhin doppelt so schnell und dabei mit geringerem Speicherverbrauch.
Neues
Null coalescing Operator (??)
Spaceship-Operator (<=>)
Array Konstanten
Anonyme Klassen
Exception Handling
Sodium - Neue Krypto-Bibliothek (Libsodium)
Null coalescing Operator (??)
$sortBy = $_GET['sortBy'] ?: 'name';
Problem, wenn "sortBy" nicht gesetzt.
Lösung bisher:
$sortBy = isset($_GET['sortBy']) ? $_GET['sortBy'] : 'name';
Lösung mit PHP 7:
$sortBy = $_GET['sortBy'] ?? 'name';
Spaceship-Operator (<=>)
Ein Drei-Wege-Vergleich, vereinfacht Sortierungen.
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
echo [] <=> []; // 0
echo [1, 2, 3] <=> [1, 2, 3]; // 0
echo [1, 2, 3] <=> []; // 1
echo [1, 2, 3] <=> [1, 2, 1]; // 1
echo [1, 2, 3] <=> [1, 2, 4]; // -1
Array Konstanten
Konstanten können nun auch ein Array beinhalten:
define('FARBEN' , ['rot', 'blau', 'grün']);
echo FARBEN[0]; // rot
Anonyme Klassen
interface Logger
{
public function log($message);
}
$echoLogger = new class implements Logger {
public function log($message)
{
echo $message . "\n";
}
};
$echoLogger->log("Hello World!");
Exception Handling
Alle fatalen Fehler sind in PHP 7 Exceptions. Diese können nun abgefangen werden, ohne sofortigen Abbruch des Programms.
Dazu gehört zum Beispiel der ehemals fatale Fehler:
"Call to a member function ?() on a non object".
$foo = null;
$foo->methodCall();
Exception Handling
Laufzeitfehler, genau wie Exceptions, werde nun von einem neuen Interface Throwable abgeleitet.
Diese können nun entweder über dieses Interface oder die Basisklasse Error abgefangen werden.
Achtung: “Error” != “Exception”
$foo = null;
try {
$foo->methodCall();
} catch (Exception $ex) {
echo "Fehler: " . $ex->getMessage();
}
// PHP Fatal Error....
Exception Handling
In PHP 7 nun möglich:
$foo = null;
try {
$foo->methodCall();
} catch (Error $ex) {
echo "Fehler: " . $ex->getMessage();
}
// Fehler: Call to a member function ...
Exception Handling
Mit catch (Throwable) lassen sich Exceptions und Errors fangen:
$foo = null;
try {
$foo->methodCall();
} catch (Throwable $ex) {
echo "Fehler: " . $ex->getMessage();
}
// Fehler: Call to a member function ...
Exception Handling
Variante die kompatibel ist mit PHP 5 und PHP 7:
try {
// Code that may throw an Exception or Error.
} catch (Throwable $t) {
// Executed only in PHP 7, will not match in PHP 5.x
} catch (Exception $e) {
// Executed only in PHP 5.x, will not be reached in PHP 7
}
Removed Extensions
- ext/mssql
- ext/mysql
- ext/sybase_ct
- ext/ereg
- ext/mcrypt (deprecated ab 7.1, ab 7.2 moved to PECL)
Inkompatibilitäten
Inkompatible Features
Skalare Typehints
Uniform variable syntax (Auswertungsreihenfolge)
Änderungen bei 'list'
Änderungen bei 'foreach'
func_get_args()
Skalare Typehints
Vor PHP 7 waren Typehints nur für Objekte und Arrays möglich. Nun auch für primitive Datentypen.
Daher ist es nun nicht mehr möglich, Klassen, Interfaces, Traits wie folgt im Namen zu deklarieren: (case-insensitive)
ab 7.0: bool, int, float, string, null, false, true
ab 7.1: void, iterable
ab 7.2: object
Das betrifft auch die Verwendung der Namen bei class_alias()
und use
Statements.
Für die Zukunft sind folgende Namen reserviert, erzeugen aber noch keine Fehlermeldung:
resource, mixed, numeric
Skalare Typehints
Auch der Rückgabetyp von Funktionen / Methoden kann nun vorgegeben werden! Komplettes Beispiel:
function addition (int $num1, float $num2, string $text) : string
{
return $text . ": " . ($num1 + $num2);
}
echo addition(2, 1.14, "Ergebnis");
//Ergebnis: 3.14
Skalare Typehints
Werden die Parameter vom Typ nicht eingehalten, passiert folgendes:
function addition (int $num1, float $num2, string $text) : int
{
return $text . ": " . ($num1 + $num2);
}
echo addition("2hallo", 1.14, 42);
//PHP Notice: A non well formed numeric value encountered... line 1
//PHP Notice: A non well formed numeric value encountered... line 3
//42
Skalare Typehints
Strengere Prüfung mit strict types, Ausgabe eines Fatal Errors bei Konflikten:
declare(strict_types=1);
function addition (int $num1, float $num2, string $text) : string
{
return $text . ": " . ($num1 + $num2);
}
echo addition(2, 1.14, 42);
//PHP Fatal error: Uncaught TypeError: Argument 3 ...
//must be of type string, integer given
Zulässig wäre hier trotzdem ein Integer statt Float zu übergeben, das wird konvertiert.
Hinweis: die "declare" Zeile, die am Anfang einer Datei gesetzt werden kann, muss in jeder Datei enthalten sein, wo die strenge Prüfung gewünscht ist.
Uniform variable syntax (Auswertungsreihenfolge)
Expression | PHP 5 interpretation | PHP 7 interpretation |
$$foo['bar']['baz'] | ${$foo['bar']['baz']} | ($$foo)['bar']['baz'] |
$foo->$bar['baz'] | $foo->{$bar['baz']} | ($foo->$bar)['baz'] |
$foo->$bar['baz']() | $foo->{$bar['baz']}() | ($foo->$bar)['baz']() |
Foo::$bar['baz']() | Foo::{$bar['baz']}() | (Foo::$bar)['baz']() |
Hint: Use the syntax of the PHP5 interpretation, which is also understood in PHP7.
Änderungen bei 'list'
Bei Verwendung von nur einem Array weist list()
in PHP 5 die Werte von rechts beginnend zu. In PHP 7 beginnt list()
von links.
//ohne Arrays
$info = array('Kaffee', 'braun', 'Koffein');
list($drink, $color, $power) = $info;
echo "{$drink} - {$color} - {$power}.\n";
//Kaffee - braun - Koffein.
//mit unterschiedlichen Arrays
list($a[], $b[], $c[]) = $info;
echo "$a[0] - $b[0] - $c[0].\n";
//Kaffee - braun - Koffein.
//aber mit dem selben Array
list($a[], $a[], $a[]) = $info;
echo "$a[0] - $a[1] - $a[2].\n";
//PHP 5: Koffein - braun - Kaffee.
//PHP 7: Kaffee - braun - Koffein.
Änderungen bei 'foreach'
Der interne Zeiger innerhalb von foreach im iterierten Array wird nicht mehr modifiziert. Bei zusätzlicher Verwendung der Array-Funktionen current() oder next() innerhalb einer foreach-Schleife, wird sich der entsprechende Code unter PHP 7 anders verhalten.
$array = [0, 1, 2];
foreach ($array as $key) {
var_dump(current($array));
next($array);
}
//PHP 5: int(1), int(2), bool(false)
//PHP 7: int(0), int(1), int(2)
Inkompatibilität: func_get_arg[s]()
PHP 5: func_get_arg() / func_get_args() liefert immer die Originalwerte der Funktionsparameter. Werden die Werte vor dem Aufruf verändert, werden trotzdem die alten Werte geliefert.
PHP 7: Hier würde man die veränderten Werte erhalten.
Inkompatibilität: func_get_arg()
function foo($x) {
$x++;
var_dump(func_get_arg(0));
}
foo(1);
Ergibt in PHP 5: 1
Ergibt in PHP 7: 2
Deprecated Features
“PHP 4 Style” Konstruktoren
Nicht-statische Methoden sollten nicht mehr statisch aufgerufen werden
Password hash (salt option)
Deprecated Functions
__autoload()
(ab PHP 7.2)
- Ersatz ab PHP 5.1 durch spl_autoload_register
- create_function() (ab PHP 7.2)
- Ersatz ab PHP 5.3 durch anonyme Funktionen (closures)
- each() (ab PHP 7.2)
- Ersatz wäre foreach(), ist auch schneller
Weitere Funktionen sind noch in Diskussion. (Stand: 10.02.2017)
Migrationshinweise
Migrationshinweise für Contao Erweiterungen
Anpassung Abhängigkeiten
Anpassung composer.json bzw. Einstellungen in ER2 auf Contao 3.5.5 bzw. 4.1.0 oder höher.
String Klasse ersetzen
Wurde die String
Klasse aus dem Contao Core verwendet?
Dann durch StringUtil
ersetzen. Beispiele:
String::toXhtml(...) zu StringUtil::toXhtml(...)
Achtung: Die Methoden der String Klasse wurde vor längerer Zeit statisch. Die StringUtil Klasse verlor dabei die überflüssig gewordene Methode "getInstance".
Erweiterungen mit diesem Aufruf:
$objString = String::getInstance();
müssen da eventuell noch mehr anpassen.
(z.B. die Erweiterung clipboard, siehe #14)
Indirekte Variablen
Wurde ein eigene Hook entwickelt? Der Aufruf der registrierten Klasse und Methode muss angepasst werden.
$this->$callback[0]; zu
$this->{$callback[0]};
$this->$callback[0]->$callback[1](...); zu
$this->{$callback[0]}->{$callback[1]}(...);
System::importStatic($callback[0])->$callback[1](); zu
System::importStatic($callback[0])->{$callback[1]}();
Tools
Tools um die Migration zu vereinfachen von PHP 5 auf PHP 7.
PHP 7 Compatibility Checker (php7cc)
Kommandozeilen-Tool, um die Migration von PHP 5.3-5.6 zu PHP 7 zu vereinfachen. Es sucht nach potenziell problematischen Anweisungen in bestehenden Code und erzeugt Berichte mit Dateinamen, Zeilennummern und kurze Problembeschreibungen.
PHP 7 Compatibility Checker (php7cc)
Ausgabe einer Prüfung:
File: /system/modules/core/library/Contao/String.php
> Line 29: Reserved name "string" used as a class, interface or trait name
class String
{
}
Aber Achtung: Nicht gefunden wird derzeit so etwas:
$value = \String::encodeEmail($value);
$xhtml = String::toXhtml($html5);
PHP 7 Compatibility Checker (php7cc)
Ausgabe einer Prüfung:
File: /system/modules/core/library/Contao/Database/Mysql.php
> Line 57: Removed function "mysql_connect" called
mysql_connect($strHost, $dbUser, $dbPass);
> Line 62: Removed function "mysql_query" called
mysql_query('SET sql_mode=\'\'', $this->resConnection);
...
PHP 7 Compatibility Checker (php7cc)
Ausgabe einer Prüfung:
File: /system/modules/core/modules/ModulePersonalData.php
> Line 90: Indirect variable, property or method access
$this->{$callback[0]}->{$callback[1]}();
Achtung! Hier wird bereits der korrigierte Quellcode ausgegeben. Die originale Zeile ist:
$this->$callback[0]->$callback[1]();
PHP 7 Compatibility Checker (php7cc)
Weitere Informationen auf GitHub: sstalle/php7cc
Installationen sind über Composer (global/lokal), als "phar" und als Docker Image möglich.
PHP 7 Migration Assistant Report (MAR)
Kommandozeilen-Tool, um die Migration von PHP 5.4-5.6 zu PHP 7 zu vereinfachen. Es sucht nach potenziell problematischen Anweisungen in bestehenden Code und erzeugt Berichte mit Dateinamen, Zeilennummern und kurze Problembeschreibungen.
PHP 7 Migration Assistant Report (MAR)
Ausgabe einer Prüfung:
Report located at:
/php7mar/reports/2016-08-18 22.59.28 String.md
Darin im Markdown Format sind Meldungen dieser Art:
critical
/system/modules/core/library/Contao/String.php
* reservedNames
* Line 25: `class String`
Aber Achtung: Nicht gefunden wird derzeit so etwas:
$value = \String::encodeEmail($value);
$xhtml = String::toXhtml($html5);
PHP 7 Migration Assistant Report (MAR)
Ausgabe einer Prüfung:
Report located at:
/php7mar/reports/2016-08-18 22.48.29 Mysql.md
Darin im Markdown Format sind Meldungen dieser Art:
critical
/system/modules/core/library/Contao/Database/Mysql.php
* deprecatedFunctions
* Line 47: @mysql_connect($strHost, $dbUser, $dbPass);
* Line 51: @mysql_query("SET sql_mode=''", $this->resConnection);
...
PHP 7 Migration Assistant Report (MAR)
Ausgabe einer Prüfung:
Report located at:
/php7mar/reports/2016-08-18 22.33.08 ModulePersonalData.md
Darin im Markdown Format sind Meldungen dieser Art:
critical
/system/modules/core/modules/ModulePersonalData.php
* variableInterpolation
* Line 72: ` $this->$callback[0]->$callback[1]();`
PHP 7 Migration Assistant Report (MAR)
Weitere Informationen auf GitHub: Alexia/php7mar
Installationen sind über Composer und Download/Clone möglich.
Static analyzer for PHP (Phan)
Phan ist ein statischer Code-Analyzer, von Rasmus Lerdorf ins Leben gerufen, der problematische Code-Stellen aufdeckt. Die Prüfung auf PHP 5 / PHP 7 Kompatibilität ist dabei nur ein kleiner Teil der Tests.
Static analyzer for PHP (Phan)
Ausgabe einer Prüfung: (Contao 3.2.0 in .../core/)
./classes/Ajax.php:155 PhanTypeMismatchArgumentInternal
Argument 1 (prefix) is int but \uniqid() takes string
./classes/Backend.php:432 PhanTypeMismatchReturn
Returning type null but getBackendModule() is declared to return string
./library/Contao/Controller.php:794 PhanCompatiblePHP7
Expression may not be PHP 7 compatible
./library/Contao/User.php:246 PhanCompatiblePHP7
Expression may not be PHP 7 compatible
Im Vergleich zu den beiden anderen Tools wird bezüglich PHP 7 sehr wenig gefunden, z.B. wurde die Klasse "String" nicht beanstandet.
Static analyzer for PHP (Phan)
Weitere Informationen auf GitHub: etsy/phan
Installationen sind über Composer und Download/Clone möglich.
Achtung: PHan benötigt selbst PHP 7 und die PHP Erweiterung "ast": nikic/php-ast
Linkliste
Informationen zur Migration:
- Migrating from PHP 5.6.x to PHP 7.0.x (php.net)
- Migrating from PHP 7.0.x to PHP 7.1.x (php.net)
- Mit PHP 7 wird das Internet schneller
Reporting Tools für die Kommandozeile:
Tutorials:
- php7-tutorial.com (Interaktiv)
- tutorialspoint.com/php7 (auch als PDF)
Danke!
Aktuelle Version dieser Folien auf: docs.contao.ninja
(auch als PDF und später auch als Video)