PHP 7.2 Referenz
PHP 7.1 Referenz
PHP 7 wurde am 3. Dezember 2015 veröffentlicht. Es enthält eine Reihe neuer Funktionen, Änderungen und Abwärtskompatibilitätsprobleme, die im Folgenden beschrieben werden.
Leistung
Merkmale
Kombinierter Vergleichsoperator
Null-Coalesce-Operator
Skalare Typdeklarationen
Rückgabetypdeklarationen
Anonyme Klassen
Unicode-Codepoint-Escape-Syntax
Schließung call()
Methode
Gefiltert unserialize()
IntlChar
Klasse
Erwartungen
use
Generator-Rückgabeausdrücke
Generatordelegation
Ganzzahldivision mit intdiv()
session_start()
Optionen
preg_replace_callback_array()
Funktion
CSPRNG-Funktionen
Unterstützung für Array-Konstanten in define()
Reflexionsergänzungen
Änderungen
Lockerung der Beschränkungen für reservierte Wörter
Einheitliche Variablensyntax
Ausnahmen in der Engine
Throwable-Schnittstelle
Ganzzahlige Semantik
JSON-Erweiterung durch JSOND ersetzt
ZPP-Fehler bei Überlauf
Behebt das Verhalten von foreach()
Änderungen am Verhalten von list()
Änderungen an der Division durch Nullsemantik
Korrekturen an den Rückgabewerten des benutzerdefinierten Sitzungshandlers
Veraltete PHP 4-Style-Konstruktoren
Entfernung der date.timezone-Warnung
Entfernung alternativer PHP-Tags
Entfernen mehrerer Standardblöcke in Switch-Anweisungen
Entfernung der Neudefinition von Parametern mit doppelten Namen
Entfernung toter Server-APIs
Entfernung der Hex-Unterstützung in numerischen Zeichenfolgen
Entfernung veralteter Funktionalität
Neuklassifizierung und Entfernung von E_STRICT-Hinweisen
Abschaffung der Salt-Option für password_hash()
Fehler bei ungültigen Oktalliteralen
substr()
Rückgabewertänderung
FAQ
Was ist mit PHP 6 passiert?
Das Beste an PHP 7 sind zweifellos die unglaublichen Leistungssteigerungen, die es den Anwendungen bietet. Dies ist ein Ergebnis der Umgestaltung der Zend Engine, um kompaktere Datenstrukturen und weniger Heap-Zuweisungen/Freigaben zu verwenden.
Die Leistungssteigerungen bei realen Anwendungen werden variieren, obwohl viele Anwendungen eine Leistungssteigerung von etwa 100 % zu erhalten scheinen – und das bei geringerem Speicherverbrauch!
Die überarbeitete Codebasis bietet auch weitere Möglichkeiten für zukünftige Optimierungen (z. B. JIT-Kompilierung). Es sieht also so aus, als ob zukünftige PHP-Versionen auch weiterhin Leistungsverbesserungen erfahren werden.
Vergleiche der PHP 7-Leistungsdiagramme:
Turbo für das Web mit PHP 7
Benchmarks aus Rasmus' Sydney Talk
Der kombinierte Vergleichsoperator (oder Raumschiffoperator) ist eine Kurzschreibweise für die Durchführung von Dreifachvergleichen zweier Operanden. Es hat einen ganzzahligen Rückgabewert, der entweder sein kann:
eine positive ganze Zahl (wenn der linke Operand größer als der rechte Operand ist)
0 (wenn beide Operanden gleich sind)
eine negative ganze Zahl (wenn der rechte Operand größer als der linke Operand ist)
Der Operator hat die gleiche Priorität wie die Gleichheitsoperatoren ( ==
, !=
, ===
, !==
) und weist genau das gleiche Verhalten auf wie die anderen losen Vergleichsoperatoren ( <
, >=
usw.). Es ist wie diese auch nicht assoziativ, daher ist eine Verkettung der Operanden (wie 1 <=> 2 <=> 3
) nicht zulässig.
// vergleicht Strings lexikalischvar_dump('PHP' <=> 'Node'); // int(1)// vergleicht Zahlen nach sizevar_dump(123 <=> 456); // int(-1)// vergleicht entsprechende Array-Elemente mit one-anothervar_dump(['a', 'b'] <=> ['a', 'b']); // int(0)
Objekte sind nicht vergleichbar und ihre Verwendung als Operanden mit diesem Operator führt daher zu undefiniertem Verhalten.
RFC: Kombinierter Vergleichsoperator
Der Null-Coalesce-Operator (oder der ternäre Operator isset) ist eine Kurzschreibweise für die Durchführung isset()
-Prüfungen im ternären Operator. Da dies in Anwendungen häufig vorkommt, wurde für genau diesen Zweck eine neue Syntax eingeführt.
// Vor PHP 7 code$route = isset($_GET['route']) ? $_GET['route'] : 'index';// PHP 7+ code$route = $_GET['route'] ?? 'Index';
RFC: Null-Coalesce-Operator
Skalare Typdeklarationen gibt es in zwei Varianten: „coercive“ (Standard) und „strict“ . Die folgenden Parametertypen können jetzt erzwungen werden (entweder zwangsweise oder streng): Zeichenfolgen ( string
), Ganzzahlen ( int
), Gleitkommazahlen ( float
) und Boolesche Werte ( bool
). Sie ergänzen die anderen in den PHP 5.x-Versionen eingeführten Typen: Klassennamen, Schnittstellen, array
und callable
.
// Zwangsmodusfunktion sumOfInts(int ...$ints) { return array_sum($ints); }var_dump(sumOfInts(2, '3', 4.1)); // int(9)
Um den strikten Modus zu aktivieren, muss eine einzelne declare()
-Direktive am Anfang der Datei platziert werden. Dies bedeutet, dass die Strenge der Typisierung für Skalare für jede einzelne Datei konfiguriert wird. Diese Direktive wirkt sich nicht nur auf die Typdeklarationen von Parametern aus, sondern auch auf den Rückgabetyp einer Funktion (siehe Rückgabetypdeklarationen), integrierte PHP-Funktionen und Funktionen aus geladenen Erweiterungen.
Wenn die Typprüfung fehlschlägt, wird eine TypeError
Ausnahme (siehe Ausnahmen in der Engine) ausgelöst. Die einzige Nachsicht bei der strikten Typisierung ist die automatische Konvertierung von Ganzzahlen in Gleitkommazahlen (aber nicht umgekehrt), wenn eine Ganzzahl in einem Gleitkommakontext bereitgestellt wird.
deklarieren(strict_types=1);Funktion multiplizieren(float $x, float $y) { return $x * $y; }Funktion add(int $x, int $y) { return $x + $y; }var_dump(multiply(2, 3.5)); // float(7)var_dump(add('2', 3)); // Schwerwiegender Fehler: Uncaught TypeError: Das an add() übergebene Argument 1 muss vom Typ „Integer“ sein, die angegebene Zeichenfolge ...
Beachten Sie, dass bei der Typprüfung nur der Aufrufkontext gilt. Dies bedeutet, dass die strikte Typisierung nur für Funktions-/Methodenaufrufe gilt und nicht für die Funktions-/Methodendefinitionen. Im obigen Beispiel hätten die beiden Funktionen entweder in einer strikten oder erzwungenen Datei deklariert werden können, aber solange sie in einer strikten Datei aufgerufen werden, gelten die strengen Typisierungsregeln.
BC Pausen
Klassen mit den Namen int
, string
, float
und bool
sind jetzt verboten.
RFC: Skalare Typdeklarationen
Rückgabetypdeklarationen ermöglichen die Angabe des Rückgabetyps einer Funktion, Methode oder eines Abschlusses. Die folgenden Rückgabetypen werden unterstützt: string
, int
, float
, bool
, array
, callable
, self
(nur Methoden), parent
(nur Methoden), Closure
, der Name einer Klasse und der Name einer Schnittstelle.
Funktion arraysSum(array ...$arrays): array{ return array_map(function(array $array): int { return array_sum($array); }, $arrays); }print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));/* OutputArray( [0] => 6 [1] => 15 [2] => 24)*/
Im Hinblick auf die Subtypisierung wurde für die Rückgabetypen die Invarianz gewählt. Dies bedeutet einfach, dass, wenn eine Methode entweder in einer untertypisierten Klasse überschrieben oder wie in einem Vertrag definiert implementiert wird, ihr Rückgabetyp genau mit der Methode übereinstimmen muss, die sie (erneut) implementiert.
Klasse A {}Klasse B erweitert A {}Klasse C { öffentliche Funktion test(): A { neues A zurückgeben; } }Klasse D erweitert C { // überschreibt Methode C::test(): Eine öffentliche Funktion test(): B // Schwerwiegender Fehler aufgrund einer Varianzinkongruenz { neues B zurückgeben; } }
Die überschreibende Methode D::test() : B
verursacht einen E_COMPILE_ERROR
, da Kovarianz nicht zulässig ist. Damit dies funktioniert, muss die Methode D::test()
den Rückgabetyp A
haben.
Klasse A {}Schnittstelle SomeInterface { public function test() : A; }Klasse B implementiert SomeInterface { public function test() : A // alles gut! { return null; // Schwerwiegender Fehler: Uncaught TypeError: Rückgabewert von B::test() muss eine Instanz von A sein, null zurückgegeben ... } }
Diesmal führt die implementierte Methode dazu, dass bei der Ausführung eine TypeError
Ausnahme (siehe Ausnahmen in der Engine) ausgelöst wird. Dies liegt daran, dass null
kein gültiger Rückgabetyp ist – es kann nur eine Instanz der Klasse A
zurückgegeben werden.
RFC: Rückgabetypdeklarationen
Anonyme Klassen sind nützlich, wenn einfache, einmalige Objekte erstellt werden müssen.
// Codeklassen-Logger vor PHP 7 { öffentliches Funktionsprotokoll($msg) { echo $msg; } }$util->setLogger(new Logger());// PHP 7+ code$util->setLogger(new class { public function log($msg) { echo $msg; } });
Sie können Argumente an ihre Konstruktoren weitergeben, andere Klassen erweitern, Schnittstellen implementieren und Merkmale verwenden, genau wie eine normale Klasse:
Klasse SomeClass {}interface SomeInterface {}trait SomeTrait {}var_dump(neue Klasse(10) erweitert SomeClass implementiert SomeInterface { private $num; öffentliche Funktion __construct($num) { $this->num = $num; } use SomeTrait; });/** Output:object(class@anonymous)#1 (1) { ["Befehlszeilencode0x104c5b612":"class@anonymous":private]=> int(10)}*/
Durch die Verschachtelung einer anonymen Klasse in einer anderen Klasse erhält diese keinen Zugriff auf private oder geschützte Methoden oder Eigenschaften dieser äußeren Klasse. Um die geschützten Eigenschaften oder Methoden der äußeren Klasse zu nutzen, kann die anonyme Klasse die äußere Klasse erweitern. Um die privaten oder geschützten Eigenschaften der äußeren Klasse in der anonymen Klasse zu verwenden, müssen sie über deren Konstruktor übergeben werden:
<?phpclass Outer { private $prop = 1; geschützt $prop2 = 2; geschützte Funktion func1() { return 3; } öffentliche Funktion func2() { return new class($this->prop) erweitert Outer { private $prop3; öffentliche Funktion __construct($prop) { $this->prop3 = $prop; } öffentliche Funktion func3() { return $this->prop2 + $this->prop3 + $this->func1(); } }; } }echo (new Outer)->func2()->func3(); // 6
RFC: Anonyme Klassen
Dies ermöglicht die Ausgabe eines UTF-8-codierten Unicode-Codepunkts entweder in einer Zeichenfolge in doppelten Anführungszeichen oder in einem Heredoc. Jeder gültige Codepunkt wird akzeptiert, wobei führende 0
optional sind.
echo „u{aa}“; // ªecho "u{0000aa}"; // ª (wie zuvor, aber optional mit führenden Nullen)echo "u{9999}"; // 香
RFC: Unicode-Codepoint-Escape-Syntax
Die neue call()
Methode für Abschlüsse wird als Abkürzung zum Aufrufen eines Abschlusses verwendet, während gleichzeitig ein Objektbereich daran gebunden wird. Dadurch entsteht leistungsfähigerer und kompakterer Code, da vor dem Aufruf kein Zwischenabschluss erstellt werden muss.
class A {private $x = 1;}// Code vor PHP 7$getXCB = function() {return $this->x;};$getX = $getXCB->bindTo(new A, 'A'); // Zwischenabschlussecho $getX(); // 1// PHP 7+ code$getX = function() {return $this->x;};echo $getX->call(new A); // 1
RFC: Schließung::Aufruf
unserialize()
Diese Funktion soll eine bessere Sicherheit beim Deserialisieren von Objekten auf nicht vertrauenswürdigen Daten bieten. Es verhindert mögliche Code-Injektionen, indem es dem Entwickler ermöglicht, Klassen, die unserialisiert werden können, auf die Whitelist zu setzen.
// konvertiert alle Objekte in __PHP_Incomplete_Class object$data = unserialize($foo, ["allowed_classes" => false]);// konvertiert alle Objekte in __PHP_Incomplete_Class-Objekte außer denen von MyClass und MyClass2$data = unserialize($foo, [" erlaubte_Klassen" => ["MyClass", "MyClass2"]]);// Standardverhalten (dasselbe wie das Weglassen des zweiten Arguments), das akzeptiert alle Klassen$data = unserialize($foo, ["allowed_classes" => true]);
RFC: Gefiltertes unserialize()
IntlChar
Klasse Die neue IntlChar
Klasse versucht, zusätzliche ICU-Funktionalität bereitzustellen. Die Klasse selbst definiert eine Reihe statischer Methoden und Konstanten, die zur Manipulation von Unicode-Zeichen verwendet werden können.
printf('%x', IntlChar::CODEPOINT_MAX); // 10ffffecho IntlChar::charName('@'); // KOMMERZIELL ATvar_dump(IntlChar::ispunct('!')); // bool(true)
Um diese Klasse nutzen zu können, muss die Intl
Erweiterung installiert sein.
BC Pausen
Klassen im globalen Namespace dürfen nicht IntlChar
heißen.
RFC: IntlChar-Klasse
Erwartungen sind eine abwärtskompatible Erweiterung der älteren Funktion assert()
. Sie ermöglichen kostenlose Behauptungen im Produktionscode und bieten die Möglichkeit, bei Fehlern benutzerdefinierte Ausnahmen auszulösen.
Der Prototyp der Funktion assert()
lautet wie folgt:
void assert (mixed $expression [, mixed $message]);
Wie bei der alten API wird $expression
ausgewertet, wenn es sich um eine Zeichenfolge handelt. Wenn das erste Argument falsch ist, schlägt die Behauptung fehl. Das zweite Argument kann entweder eine einfache Zeichenfolge sein (die dazu führt, dass ein AssertionError ausgelöst wird) oder ein benutzerdefiniertes Ausnahmeobjekt, das eine Fehlermeldung enthält.
ini_set('assert.Exception', 1);class CustomError erweitert AssertionError {}assert(false, new CustomError('Some error message'));
Mit dieser Funktion sind zwei PHP.ini-Einstellungen (zusammen mit ihren Standardwerten) verbunden:
zend.assertions = 1
Assert.Exception = 0
zend.assertions hat drei Werte:
1 = Code generieren und ausführen (Entwicklungsmodus)
0 = Code generieren und zur Laufzeit darin herumspringen
-1 = keinen Code generieren (kostenlos, Produktionsmodus)
„assertion.Exception“ bedeutet, dass eine Ausnahme ausgelöst wird, wenn eine Behauptung fehlschlägt. Dies ist standardmäßig ausgeschaltet, um die Kompatibilität mit der alten Funktion assert()
zu gewährleisten.
RFC: Erwartungen
use
Dies gibt die Möglichkeit, mehrere use
entsprechend dem übergeordneten Namespace zu gruppieren. Dadurch wird versucht, die Ausführlichkeit des Codes zu beseitigen, wenn mehrere Klassen, Funktionen oder Konstanten importiert werden, die unter demselben Namespace liegen.
// Code vor PHP 7use somenamespaceClassA;use somenamespaceClassB;use somenamespaceClassC as C;use function somenamespacefn_a;use function somenamespacefn_b;use function somenamespace fn_c;use const somenamespaceConstA;use const somenamespaceConstB;use const somenamespaceConstC;// PHP 7+ Codeuse somenamespace{ClassA, ClassB, ClassC as C};Funktion verwenden somenamespace{fn_a, fn_b, fn_c};const verwenden somenamespace{ConstA, ConstB, ConstC};
RFC: Gruppennutzungserklärungen
Diese Funktion baut auf der in PHP 5.5 eingeführten Generatorfunktionalität auf. Es ermöglicht die Verwendung einer return
Anweisung innerhalb eines Generators, um die Rückgabe eines endgültigen Ausdrucks zu ermöglichen (die Rückgabe per Referenz ist nicht zulässig). Dieser Wert kann mit der neuen Methode Generator::getReturn()
abgerufen werden, die nur verwendet werden darf, wenn der Generator über endgültige Ergebniswerte verfügt.
// IIFE-Syntax jetzt möglich – siehe Unterabschnitt „Einheitliche Variablensyntax“ im Abschnitt „Änderungen“$gen = (function() { yield 1; yield 2; return 3; })();foreach ($gen as $val) { echo $val, PHP_EOL; }echo $gen->getReturn(), PHP_EOL;// Ausgabe:// 1// 2// 3
Die Möglichkeit, explizit einen Endwert von einem Generator zurückzugeben, ist eine praktische Möglichkeit. Dies liegt daran, dass dadurch ein Endwert von einem Generator zurückgegeben werden kann (vielleicht aus einer Form der Coroutine-Berechnung), der vom Client-Code, der den Generator ausführt, speziell verarbeitet werden kann. Dies ist weitaus einfacher, als den Clientcode zu zwingen, zunächst zu prüfen, ob der endgültige Wert geliefert wurde, und diesen Wert dann, wenn ja, speziell zu verarbeiten.
RFC: Generator-Rückgabeausdrücke
Die Generatordelegierung basiert auf der Fähigkeit, Ausdrücke von Generatoren zurückgeben zu können. Dies geschieht durch die Verwendung einer neuen Syntax von yield from <expr>
, wobei es sich um ein Traversable
Objekt oder Array handeln kann. Dies wird so lange fortgeführt, bis es nicht mehr gültig ist, und dann wird die Ausführung im aufrufenden Generator fortgesetzt. Diese Funktion ermöglicht die Aufteilung yield
-Anweisungen in kleinere Vorgänge und fördert so einen saubereren Code mit größerer Wiederverwendbarkeit.
Funktion gen() { Ausbeute 1; Ausbeute 2; return yield von gen2(); }Funktion gen2() { Ausbeute 3; Rückkehr 4; }$gen = gen();foreach ($gen as $val) { echo $val, PHP_EOL; }echo $gen->getReturn();// Ausgabe// 1// 2// 3// 4
RFC: Generatordelegation
intdiv()
Die Funktion intdiv()
wurde eingeführt, um Divisionen zu verarbeiten, bei denen eine Ganzzahl zurückgegeben werden soll.
var_dump(intdiv(10, 3)); // int(3)
BC Pausen
Funktionen im globalen Namensraum dürfen nicht intdiv
aufgerufen werden.
RFC: intdiv()
session_start()
Optionen Diese Funktion bietet die Möglichkeit, ein Array von Optionen an die Funktion session_start()
zu übergeben. Dies wird verwendet, um sitzungsbasierte php.ini-Optionen festzulegen:
session_start(['cache_limiter' => 'private']); // setzt die Option session.cache_limiter auf privat
Diese Funktion führt außerdem eine neue php.ini-Einstellung ( session.lazy_write
) ein, die standardmäßig auf „true“ gesetzt ist und bedeutet, dass Sitzungsdaten nur dann neu geschrieben werden, wenn sie sich ändern.
RFC: Einführung von session_start()-Optionen
preg_replace_callback_array()
Funktion Diese neue Funktion ermöglicht ein saubereres Schreiben von Code bei Verwendung der Funktion preg_replace_callback()
. Vor PHP 7 erforderten Rückrufe, die per regulärem Ausdruck ausgeführt werden mussten, dass die Rückruffunktion (zweiter Parameter von preg_replace_callback()
) mit vielen Verzweigungen verunreinigt war (bestenfalls eine hackige Methode).
Jetzt können Rückrufe für jeden regulären Ausdruck mithilfe eines assoziativen Arrays registriert werden, wobei der Schlüssel ein regulärer Ausdruck und der Wert ein Rückruf ist.
Funktionssignatur:
string preg_replace_callback_array(array $regexesAndCallbacks, string $input);
$tokenStream = []; // [tokenName, lexeme]pairs$input = <<<'end'$a = 3; // Variable initialisationend;// Pre PHP 7 codepreg_replace_callback( [ '~$[a-z_][azd_]*~i', '~=~', '~[d]+~', '~;~', '~//.*~' ], Funktion ($match) use (&$tokenStream) { if (strpos($match[0], '$') === 0) { $tokenStream[] = ['T_VARIABLE', $match[0]] ; } elseif (strpos($match[0], '=') === 0) { $tokenStream[] = ['T_ASSIGN', $match[0]]; } elseif (ctype_digit($match[0])) { $tokenStream[] = ['T_NUM', $match[0]]; } elseif (strpos($match[0], ';') === 0) { $tokenStream[] = ['T_TERMINATE_STMT', $match[0]]; } elseif (strpos($match[0], '//') === 0) { $tokenStream[] = ['T_COMMENT', $match[0]]; } }, $input);// PHP 7+ codepreg_replace_callback_array( [ '~$[a-z_][azd_]*~i' => function ($match) use (&$tokenStream) { $tokenStream[] = ['T_VARIABLE', $match[0]]; }, '~=~' => function ($match) use (&$tokenStream) { $tokenStream[] = ['T_ASSIGN', $match[0]]; }, '~[d]+~' => function ($match) use (&$tokenStream) { $tokenStream[] = ['T_NUM', $match[0]]; }, '~;~' => function ($match) use (&$tokenStream) { $tokenStream[] = ['T_TERMINATE_STMT', $match[0]]; }, '~//.*~' => function ($match) use (&$tokenStream) { $tokenStream[] = ['T_COMMENT', $match[0]]; } ], $input);
BC Pausen
Funktionen im globalen Namensraum dürfen nicht preg_replace_callback_array
heißen.
RFC: Funktion preg_replace_callback_array hinzufügen
Mit dieser Funktion werden zwei neue Funktionen zum Generieren kryptografisch sicherer Ganzzahlen und Zeichenfolgen eingeführt. Sie stellen einfache APIs zur Verfügung und sind plattformunabhängig.
Funktionssignaturen:
string random_bytes(int length); int random_int(int min, int max);
Beide Funktionen geben eine Error
aus, wenn keine Quelle mit ausreichender Zufälligkeit gefunden werden kann.
BC Pausen
Funktionen im globalen Namespace dürfen nicht random_int
oder random_bytes
heißen.
RFC: Einfaches User-Land-CSPRNG
define()
Die Möglichkeit, Array-Konstanten zu definieren, wurde in PHP 5.6 mit dem Schlüsselwort const
eingeführt. Diese Fähigkeit wurde nun auch auf die Funktion define()
angewendet:
define('ALLOWED_IMAGE_EXTENSIONS', ['jpg', 'jpeg', 'gif', 'png']);
RFC: kein RFC verfügbar
In PHP 7 wurden zwei neue Reflexionsklassen eingeführt. Die erste ist ReflectionGenerator
, die zur Selbstbeobachtung von Generatoren verwendet wird:
Klasse ReflectionGenerator { public __construct(Generator $gen) öffentliches Array getTrace($options = DEBUG_BACKTRACE_PROVIDE_OBJECT) public int getExecutingLine(void) öffentliche Zeichenfolge getExecutingFile(void) öffentliche ReflectionFunctionAbstract getFunction(void) öffentliches Objekt getThis(void) öffentlicher Generator getExecutingGenerator(void) }
Der zweite ist ReflectionType
um die Deklarationsfunktionen für Skalar- und Rückgabetypen besser zu unterstützen:
Klasse ReflectionType { public bool erlaubtNull(void) public bool isBuiltin(void) public string __toString(void) }
Außerdem wurden zwei neue Methoden in ReflectionParameter
eingeführt:
Klasse ReflectionParameter { // ... public bool hasType(void) public ReflectionType getType(void) }
Sowie zwei neue Methoden in ReflectionFunctionAbstract
:
Klasse ReflectionFunctionAbstract { // ... public bool hasReturnType(void) public ReflectionType getReturnType(void) }
BC Pausen
Klassen im globalen Namespace dürfen nicht ReflectionGenerator
oder ReflectionType
heißen.
RFC: kein RFC verfügbar
Global reservierte Wörter als Eigenschafts-, Konstanten- und Methodennamen innerhalb von Klassen, Schnittstellen und Merkmalen sind jetzt zulässig. Dies reduziert die Oberfläche von BC-Unterbrechungen, wenn neue Schlüsselwörter eingeführt werden, und vermeidet Namensbeschränkungen für APIs.
Dies ist besonders nützlich, wenn interne DSLs mit fließenden Schnittstellen erstellt werden:
// 'new', 'private' und 'for' waren bisher unbrauchbarProject::new('Project Name')->private()->for('zweck hier')->with('username hier');
Die einzige Einschränkung besteht darin, dass das Schlüsselwort class
immer noch nicht als konstanter Name verwendet werden kann, da es sonst zu Konflikten mit der Syntax zur Klassennamenauflösung ( ClassName::class
) führen würde.
RFC: Kontextsensitiver Lexer
Diese Änderung führt zu einer weitaus größeren Orthogonalität der Variablenoperatoren in PHP. Es ermöglicht eine Reihe neuer Kombinationen von Operatoren, die zuvor nicht zulässig waren, und führt so neue Möglichkeiten ein, alte Operationen in kürzerem Code zu erreichen.
// Verschachtelung von ::$foo::$bar::$baz // Zugriff auf die Eigenschaft $baz der Eigenschaft $foo::$bar // Verschachtelung von ()foo()() // Aufruf der Rückgabe von foo() // Operatoren für in ()(function () {})() eingeschlossene Ausdrücke // IIFE-Syntax von JS
Die Möglichkeit, Variablenoperatoren beliebig zu kombinieren, entstand durch die Umkehrung der Auswertungssemantik indirekter Variablen-, Eigenschafts- und Methodenreferenzen. Das neue Verhalten ist intuitiver und folgt immer einer Bewertungsreihenfolge von links nach rechts:
// alte Bedeutung // neue Bedeutung$$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']()
BC Pausen
Code, der auf der alten Auswertungsreihenfolge beruhte, muss umgeschrieben werden, um diese Auswertungsreihenfolge explizit mit geschweiften Klammern zu verwenden (siehe mittlere Spalte oben). Dadurch wird der Code sowohl vorwärtskompatibel mit PHP 7.x als auch rückwärtskompatibel mit PHP 5.x
RFC: Einheitliche Variablensyntax
Ausnahmen in der Engine wandeln viele schwerwiegende und behebbare schwerwiegende Fehler in Ausnahmen um. Dies ermöglicht eine sanfte Verschlechterung von Anwendungen durch benutzerdefinierte Fehlerbehandlungsverfahren. Dies bedeutet auch, dass bereinigungsgesteuerte Funktionen wie die finally
Klausel und Objektdestruktoren jetzt ausgeführt werden. Darüber hinaus werden durch die Verwendung von Ausnahmen für Anwendungsfehler Stack-Traces für zusätzliche Debugging-Informationen erstellt.
function sum(float ...$numbers) : float{ return array_sum($numbers); }try { $total = sum(3, 4, null); } Catch (TypeError $typeErr) { // Typfehler hier behandeln}
Die neue Ausnahmehierarchie lautet wie folgt:
interface Throwable |- Exception implements Throwable |- ... |- Error implements Throwable |- TypeError extends Error |- ParseError extends Error |- AssertionError extends Error |- ArithmeticError extends Error |- DivisionByZeroError extends ArithmeticError
Weitere Informationen zu dieser neuen Ausnahmehierarchie finden Sie im Unterabschnitt Throwable Interface im Abschnitt Änderungen.
BC Pausen
Benutzerdefinierte Fehlerhandler, die zur Behandlung (und normalerweise zum Ignorieren) behebbarer schwerwiegender Fehler verwendet werden, funktionieren nicht mehr, da jetzt Ausnahmen ausgelöst werden
Parse-Fehler, die im eval()
ed-Code auftreten, werden nun zu Ausnahmen und erfordern, dass sie in einen try...catch
Block eingeschlossen werden
RFC: Ausnahmen in der Engine
Diese Änderung wirkt sich aufgrund der Einführung von Ausnahmen in der Engine auf die Ausnahmehierarchie von PHP aus. Anstatt schwerwiegende und behebbare schwerwiegende Fehler unter die bereits vorhandene Exception
-Klassenhierarchie zu stellen, wurde beschlossen, eine neue Ausnahmehierarchie zu implementieren, um zu verhindern, dass PHP 5.x-Code diese neuen Ausnahmen mit Catch-All ( catch (Exception $e)
abfängt. ) Klauseln.
Die neue Ausnahmehierarchie lautet wie folgt:
interface Throwable |- Exception implements Throwable |- ... |- Error implements Throwable |- TypeError extends Error |- ParseError extends Error |- AssertionError extends Error |- ArithmeticError extends Error |- DivisionByZeroError extends ArithmeticError
Die Throwable
-Schnittstelle wird sowohl von Exception
als auch von Error
Basisklassenhierarchien implementiert und definiert den folgenden Vertrag:
interface Throwable { final public string getMessage ( void ) final public mixed getCode ( void ) final public string getFile ( void ) final public int getLine ( void ) final public array getTrace ( void ) final public string getTraceAsString ( void ) public string __toString ( void ) }
Throwable
kann nicht durch benutzerdefinierte Klassen implementiert werden. Stattdessen sollte eine benutzerdefinierte Ausnahmeklasse eine der bereits vorhandenen Ausnahmeklassen in PHP erweitern.
RFC: Throwable Interface
Die Semantik einiger ganzzahlbasierter Verhaltensweisen wurde geändert, um sie intuitiver und plattformunabhängiger zu machen. Hier ist eine Liste dieser Änderungen:
Die Umwandlung NAN
und INF
in eine Ganzzahl führt immer zu 0
Bitweises Verschieben um eine negative Anzahl von Bits ist jetzt nicht zulässig (verursacht eine bool(false)-Rückgabe und gibt eine E_WARNING aus)
Bitweise Verschiebungen nach links um eine Anzahl von Bits über die Bitbreite einer Ganzzahl hinaus führen immer zu 0
Bitweise Verschiebungen nach rechts um eine Anzahl von Bits über die Bitbreite einer Ganzzahl hinaus führen immer zu 0 oder -1 (vorzeichenabhängig).
BC Pausen
Jegliches Vertrauen auf die alte Semantik für das oben Genannte wird nicht mehr funktionieren
RFC: Ganzzahlige Semantik
Die Lizenzierung der alten JSON-Erweiterung galt als unfrei, was bei vielen Linux-basierten Distributionen zu Problemen führte. Die Erweiterung wurde inzwischen durch JSOND ersetzt und bringt einige Leistungssteigerungen und Abwärtskompatibilitätsprobleme mit sich.
BC Pausen
Eine Zahl darf nicht mit einem Dezimalpunkt enden (z. B. 34.
muss entweder in 34.0
oder nur in 34
geändert werden).
Der e
Exponent darf nicht direkt auf den Dezimalpunkt folgen (d. h. 3.e3
muss entweder in 3.0e3
oder einfach in 3e3
geändert werden).
RFC: Ersetzen Sie die aktuelle JSON-Erweiterung durch Jsond
Eine Umwandlung von Gleitkommazahlen in Ganzzahlen kann auftreten, wenn eine Gleitkommazahl an eine interne Funktion übergeben wird, die eine Ganzzahl erwartet. Wenn der Gleitkommawert zu groß ist, um als Ganzzahl dargestellt zu werden, wird der Wert stillschweigend abgeschnitten (was zu einem Verlust von Größe und Vorzeichen führen kann). Dies kann zu schwer zu findenden Fehlern führen. Diese Änderung zielt daher darauf ab, den Entwickler zu benachrichtigen, wenn eine implizite Konvertierung von einer Gleitkommazahl in eine Ganzzahl stattgefunden hat und fehlgeschlagen ist, indem null
zurückgegeben und eine E_WARNING ausgegeben wird.
BC Pausen
Code, der früher stillschweigend funktionierte, gibt jetzt eine E_WARNING aus und schlägt möglicherweise fehl, wenn das Ergebnis des Funktionsaufrufs direkt an eine andere Funktion übergeben wird (da jetzt null
übergeben wird).
RFC: ZPP-Fehler bei Überlauf
foreach()
foreach()
Schleife von PHP hatte eine Reihe seltsamer Randfälle. Diese waren alle durch die Implementierung gesteuert und verursachten eine Menge undefiniertes und inkonsistentes Verhalten beim Durchlaufen zwischen Kopien und Referenzen eines Arrays, bei der Verwendung von Iteratormanipulatoren wie current()
und reset()
, beim Ändern des gerade iterierten Arrays usw.
Diese Änderung beseitigt das undefinierte Verhalten dieser Randfälle und macht die Semantik vorhersehbarer und intuitiver.
foreach()
nach Wert auf Arrays
$array = [1,2,3];$array2 = &$array;foreach($array as $val) { unset($array[1]); // Array ändern, über das iteriert wird echo "{$val} - ", current($array), PHP_EOL; }// Pre PHP 7 result1 - 33 -// PHP 7+ result1 - 12 - 13 - 1
Bei Verwendung der Wertsemantik wird das Array, über das iteriert wird, jetzt nicht direkt geändert. current()
hat jetzt auch ein definiertes Verhalten, bei dem es immer am Anfang des Arrays beginnt.
foreach()
nach Referenz auf Arrays und Objekte und nach Wert auf Objekten
$array = [1,2,3];foreach($array as &$val) { echo "{$val} - ", current($array), PHP_EOL; }// Pre PHP 7 result1 - 22 - 33 -// PHP 7+ result1 - 12 - 13 - 1
Die Funktion current()
wird von der Iteration von foreach()
im Array nicht mehr beeinflusst. Außerdem funktionieren verschachtelte foreach()
's, die By-Reference-Semantik verwenden, jetzt unabhängig voneinander:
$array = [1,2,3];foreach($array as &$val) { echo $val, PHP_EOL; foreach ($array as &$val2) { unset($array[1]); echo $val, PHP_EOL; } }// Vor PHP 7 result111// PHP 7+ result111333
BC Pausen
Jegliches Vertrauen auf die alte (skurrile und undokumentierte) Semantik wird nicht mehr funktionieren.
RFC: „foreach“-Verhalten behoben
list()
Es wurde dokumentiert, dass die Funktion list()
keine Zeichenfolgen unterstützt, in einigen Fällen hätten jedoch Zeichenfolgen verwendet werden können:
// Array-Dereferenzierung$str[0] = 'ab';list($a, $b) = $str[0];echo $a; // aecho $b; // b// Objektdereferenzierung$obj = new StdClass();$obj->prop = 'ab';list($a, $b) = $obj->prop;echo $a; // aecho $b; // b// Funktion returnfunction func() { return 'ab'; }list($a, $b) = func();var_dump($a, $b);echo $a; // aecho $b; // B
Dies wurde nun geändert, sodass die Verwendung von Zeichenfolgen mit list()
in allen Fällen verboten ist.
Außerdem stellen leere list()
-Elemente jetzt einen schwerwiegenden Fehler dar und die Reihenfolge der Zuweisung von Variablen wurde von links nach rechts geändert:
$a = [1, 2];list($a, $b) = $a;// ALT: $a = 1, $b = 2// NEU: $a = 1, $b = null + "Undefiniert index 1"$b = [1, 2];list($a, $b) = $b;// ALT: $a = null + "Undefinierter Index 0", $b = 2// NEU: $a = 1, $b = 2
BC Pausen
Es ist nicht mehr möglich, list()
einem beliebigen nicht-direkten String-Wert gleichzusetzen. null
ist nun der Wert für die Variablen $a
und $b
in den obigen Beispielen
Der Aufruf von list()
ohne Variablen führt zu einem schwerwiegenden Fehler
Das Vertrauen auf die alte Zuweisungsreihenfolge von rechts nach links wird nicht mehr funktionieren
RFC: Inkonsistenz im list()-Verhalten behoben
RFC: Abstrakter Syntaxbaum
Wenn vor PHP 7 ein Divisor für den Divisions- (/) oder den Modulus-Operator (%) 0 war, wurde ein E_WARNING ausgegeben und false
zurückgegeben. Das war unsinnig, wenn eine arithmetische Operation in manchen Fällen einen booleschen Wert zurückgab, und daher wurde das Verhalten in PHP 7 korrigiert.
Das neue Verhalten führt dazu, dass der Divisionsoperator eine Gleitkommazahl entweder als +INF, -INF oder NAN zurückgibt. Der Moduloperator E_WARNING wurde entfernt und löst (zusammen mit der neuen intdiv()
Funktion) eine DivisionByZeroError
-Ausnahme aus. Darüber hinaus kann die Funktion intdiv()
auch einen ArithmeticError
auslösen, wenn gültige Ganzzahlargumente angegeben werden, die zu einem falschen Ergebnis führen (aufgrund eines Ganzzahlüberlaufs).
var_dump(3/0); // float(INF) + E_WARNINGvar_dump(0/0); // float(NAN) + E_WARNINGvar_dump(0%0); // DivisionByZeroErrorintdiv(PHP_INT_MIN, -1); // ArithmeticError
BC Pausen
Der Divisionsoperator gibt nicht mehr false
zurück (was in einer arithmetischen Operation stillschweigend auf 0 hätte gezwungen werden können).
Der Modulo-Operator löst jetzt eine Ausnahme mit einem 0-Divisor aus, anstatt false
zurückzugeben
RFC: Kein RFC verfügbar
Bei der Implementierung benutzerdefinierter Sitzungshandler verhielten sich Prädikatfunktionen von SessionHandlerInterface
, die einen true
oder false
Rückgabewert erwarten, nicht wie erwartet. Aufgrund eines Fehlers in der vorherigen Implementierung wurde nur ein Rückgabewert -1
als falsch gewertet – was bedeutet, dass selbst wenn der boolesche false
zur Angabe eines Fehlers verwendet wurde, dieser als Erfolg gewertet wurde:
<?phpclass FileSessionHandler implementiert SessionHandlerInterface { private $savePath; Funktion open($savePath, $sessionName) { return false; // schlägt immer fehl } Funktion close(){return true;} Funktion read($id){} Funktion write($id, $data){} Funktion destroy($id){} Funktion gc($maxlifetime){} }session_set_save_handler(new FileSessionHandler());session_start(); // verursacht keinen Fehler im Code vor PHP 7
Nun schlägt das oben Gesagte mit einem schwerwiegenden Fehler fehl. Ein Rückgabewert von -1
schlägt ebenfalls weiterhin fehl, während 0
und true
weiterhin Erfolg bedeuten. Jeder andere zurückgegebene Wert führt nun zu einem Fehler und gibt eine E_WARNING aus.
BC Pausen
Wenn der boolesche Wert false
zurückgegeben wird, schlägt der Vorgang jetzt tatsächlich fehl
Wenn etwas anderes als ein boolescher Wert, 0
oder -1
zurückgegeben wird, schlägt der Vorgang fehl und es wird eine Warnung ausgegeben
RFC: Die Behandlung benutzerdefinierter Rückgabewerte des Sitzungshandlers wurde korrigiert
PHP 4-Konstruktoren wurden in PHP 5 neben dem neuen __construct()
beibehalten. Jetzt werden Konstruktoren im PHP-4-Stil veraltet und stattdessen nur noch eine einzige Methode ( __construct()
) verwendet, die bei der Objekterstellung aufgerufen werden kann. Dies liegt daran, dass die Bedingungen, ob der Konstruktor im PHP-4-Stil aufgerufen wurde, einen zusätzlichen kognitiven Overhead für Entwickler verursachten, der auch für Unerfahrene verwirrend sein könnte.
Wenn die Klasse beispielsweise in einem Namespace definiert ist oder eine __construct()
Methode vorhanden war, wurde ein Konstruktor im PHP 4-Stil als einfache Methode erkannt. Wenn es über einer __construct()
-Methode definiert wurde, würde ein E_STRICT-Hinweis ausgegeben, aber immer noch als einfache Methode erkannt.
Wenn sich die Klasse nun in PHP 7 nicht in einem Namespace befindet und keine __construct()
Methode vorhanden ist, wird der Konstruktor im PHP 4-Stil als Konstruktor verwendet, es wird jedoch ein E_DEPRECATED ausgegeben. In PHP 8 wird der Konstruktor im PHP 4-Stil immer als einfache Methode erkannt und der Hinweis E_DEPRECATED verschwindet.
BC Pausen
Benutzerdefinierte Fehlerhandler können von der Auslösung von E_DEPRECATED-Warnungen betroffen sein. Um dies zu beheben, aktualisieren Sie einfach den Namen des Klassenkonstruktors auf __construct
.
RFC: PHP 4-Konstruktoren entfernen
Wenn datums- oder zeitbasierte Funktionen aufgerufen wurden und keine Standardzeitzone festgelegt wurde, wurde eine Warnung ausgegeben. Die Lösung bestand darin, einfach die INI-Einstellung „ date.timezone
“ auf eine gültige Zeitzone zu setzen, was die Benutzer jedoch dazu zwang, eine php.ini-Datei zu haben und diese vorher zu konfigurieren. Da dies die einzige Einstellung war, mit der eine Warnung verbunden war, und die Standardeinstellung ohnehin UTC war, wurde die Warnung jetzt entfernt.
RFC: Entfernen Sie die date.timezone-Warnung
Die alternativen PHP-Tags <%
(und <%=
), %>
, <script language="php">
und </script>
wurden jetzt entfernt.
BC Pausen
Code, der auf diesen alternativen Tags basiert, muss entweder auf die normalen oder kurzen öffnenden und schließenden Tags aktualisiert werden. Dies kann entweder manuell oder automatisiert mit diesem Portierungsskript erfolgen.
RFC: Alternative PHP-Tags entfernen
Bisher war es möglich, innerhalb einer Switch-Anweisung mehrere default
anzugeben (wobei der letzte default
nur ausgeführt wurde). Diese (nutzlose) Fähigkeit wurde nun entfernt und verursacht einen schwerwiegenden Fehler.
BC Pausen
Jeder geschriebene (oder wahrscheinlicher generierte) Code, der Switch-Anweisungen mit mehreren default
erstellt, wird jetzt zu einem schwerwiegenden Fehler.
RFC: Machen Sie die Definition mehrerer Standardfälle in einem Schalter zu einem Syntaxfehler
Bisher war es möglich, Parameter mit doppelten Namen innerhalb einer Funktionsdefinition anzugeben. Diese Fähigkeit wurde jetzt entfernt und verursacht einen schwerwiegenden Fehler.
Funktion foo($version, $version) { return $version; }echo foo(5, 7);// Pre PHP 7 result7// PHP 7+ resultFataler Fehler: Neudefinition des Parameters $version in /redefinition-of-parameters.php
BC Pausen
Funktionsparameter mit doppeltem Namen werden nun zu einem schwerwiegenden Fehler.
Die folgenden SAPIs wurden aus dem Kern entfernt (die meisten davon wurden nach PECL verschoben):
sapi/aolserver
Sapi/Apache
sapi/apache_hooks
sapi/apache2filter
sapi/caudium
Sapi/Kontinuität
sapi/isapi
sapi/milter
sapi/nsapi
sapi/phttpd
sapi/pi3web
sapi/roxen
sapi/thttpd
Sapi/Smoking
sapi/webjames
ext/mssql
ext/mysql
ext/sybase_ct
ext/ereg
RFC: Entfernung toter oder noch nicht PHP7-portierter SAPIs und Erweiterungen
Eine Stringy-Hexadezimalzahl wird nicht mehr als numerisch erkannt.
var_dump(is_numeric('0x123'));var_dump('0x123' == '291');echo '0x123' + '0x123';// Pre PHP 7 resultbool(true)bool(true)582// PHP 7+ resultbool(false)bool(false)0
Der Grund für diese Änderung besteht darin, eine bessere Konsistenz bei der Handhabung stringiger Hex-Zahlen in der gesamten Sprache zu fördern. Beispielsweise erkennen explizite Umwandlungen keine stringigen Hex-Zahlen:
var_dump((int) '0x123'); // int(0)
Stattdessen sollten stringige Hex-Zahlen mit der Funktion filter_var()
validiert und konvertiert werden:
var_dump(filter_var('0x123', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX)); // int(291)
BC Pausen
Diese Änderung betrifft die Funktion is_numeric()
und verschiedene Operatoren, einschließlich ==
, +
, -
, *
, /
, %
, **
, ++
und --
RFC: Hex-Unterstützung in numerischen Zeichenfolgen entfernen
Alle veralteten Funktionen wurden entfernt, insbesondere:
Die ursprüngliche MySQL-Erweiterung (ext/mysql)
Die Ereg-Erweiterung (ext/ereg)
new
per Referenz zuweisen
Bereichsbezogene Aufrufe nicht statischer Methoden aus einem inkompatiblen $this
Kontext (z. B. Foo::bar()
von außerhalb einer Klasse, wobei bar()
keine statische Methode ist)
BC Pausen
Jeder Code, der in PHP 5 mit veralteten Warnungen ausgeführt wurde, funktioniert nicht mehr (Sie wurden gewarnt!)
RFC: Veraltete Funktionalität in PHP 7 entfernen
E_STRICT-Hinweise waren in ihrer Bedeutung schon immer eine Art Grauzone. Durch diese Änderung wird diese Fehlerkategorie vollständig entfernt und entweder wird der E_STRICT-Hinweis entfernt, er wird in einen E_DEPRECATED geändert, wenn die Funktionalität in Zukunft entfernt wird, er wird in einen E_NOTICE geändert oder er wird in einen E_WARNING hochgestuft.
BC Pausen
Da E_STRICT zur Fehlerkategorie mit dem niedrigsten Schweregrad gehört, kann jede Fehlerheraufstufung zu E_WARNING benutzerdefinierte Fehlerhandler beschädigen
RFC: E_STRICT-Hinweise neu klassifizieren
password_hash()
Mit der Einführung der neuen Passwort-Hashing-API in PHP 5.5 begannen viele damit, diese zu implementieren und ihre eigenen Salts zu generieren. Leider wurden viele dieser Salts von kryptografisch unsicheren Funktionen wie mt_rand() generiert, wodurch das Salt weitaus schwächer ist als das, was standardmäßig generiert worden wäre. (Ja, beim Hashen von Passwörtern mit dieser neuen API wird immer ein Salt verwendet!) Die Option zum Generieren von Salts wurde daher veraltet, um zu verhindern, dass Entwickler unsichere Salts erstellen.
RFC: kein RFC verfügbar
Ungültige Oktalliterale verursachen jetzt einen Analysefehler, anstatt abgeschnitten und stillschweigend ignoriert zu werden.
Echo 0678; // Parse-Fehler: Ungültiges numerisches Literal in...
BC Pausen
Alle ungültigen Oktalliterale im Code führen jetzt zu Analysefehlern
RFC: kein RFC verfügbar
substr()
Rückgabewertänderung substr()
gibt jetzt einen leeren String statt false
zurück, wenn die Startposition der Kürzung gleich der Stringlänge ist:
var_dump(substr('a', 1));// Pre PHP 7 resultbool(false)// PHP 7+ resultstring(0) ""
substr()
kann in anderen Fällen jedoch immer noch false
zurückgeben.
BC Pausen
Code, der streng auf einen bool(false)
-Rückgabewert überprüft hat, ist jetzt möglicherweise semantisch ungültig
RFC: kein RFC verfügbar
PHP 6 war die Hauptversion von PHP, die nie veröffentlicht wurde. Es sollte im Kern volle Unterstützung für Unicode bieten, aber dieser Versuch war zu ehrgeizig und führte zu zu vielen Komplikationen. Die Hauptgründe, warum Version 6 für diese neue Hauptversion übersprungen wurde, sind folgende:
Um Verwirrung vorzubeugen . Es wurden viele Ressourcen über PHP 6 geschrieben und ein Großteil der Community wusste, was darin enthalten ist. PHP 7 ist ein völlig anderes Biest mit völlig anderen Schwerpunkten (insbesondere auf Leistung) und völlig anderen Funktionssätzen. Daher wurde eine Version übersprungen, um Verwirrung oder Missverständnisse darüber zu vermeiden, was PHP 7 ist.
Schlafende Hunde liegen lassen . PHP 6 wurde als Fehlschlag angesehen und eine große Menge PHP 6-Code verbleibt immer noch im PHP-Repository. Daher wurde es als das Beste angesehen, Version 6 hinter sich zu lassen und mit der nächsten Hauptversion, Version, neu zu beginnen
RFC: Name der nächsten PHP-Version