Nicht abwärtskompatible Änderungen

Änderungen im Umgang mit Fehlern und Exceptions

Viele schwerwiegende und wiederherstellbare schwerwiegende Fehler wurden in PHP 7 in Exceptions umgewandelt. Diese Fehler-Exceptions erben von der Klasse Error, die ihrerseits die Schnittstelle Throwable implementiert (die neue Basisschnittstelle, die alle Exceptions erben).

Das bedeutet, dass benutzerdefinierte Funktionen für die Fehlerbehandlung eventuell nicht mehr ausgelöst werden, da stattdessen Exceptions ausgelöst werden (was neue schwerwiegende Fehler für nicht abgefangene Error-Exceptions verursacht).

Eine genauere Beschreibung der Funktionsweise von Fehlern in PHP 7 ist auf der Seite Fehler in PHP 7 zu finden. Dieser Migrationsleitfaden zählt lediglich die Änderungen auf, die die Abwärtskompatibilität betreffen.

Bei der Funktion set_exception_handler() ist nicht mehr gewährleistet, dass sie Exception-Objekte erhält.

Code, der einen Exception-Handler mit der Funktion set_exception_handler() unter Verwendung einer Deklaration vom Typ Exception implementiert, führt zu einem fatalen Fehler, wenn ein Error-Objekt ausgelöst wird.

Wenn der Handler sowohl mit PHP 5 als auch mit PHP 7 funktionieren soll, sollte die Typdeklaration aus dem Handler entfernt werden. Bei Code, der migriert wird, um nur unter PHP 7 zu funktionieren, genügt es stattdessen, die Exception-Typdeklaration durch Throwable zu ersetzen.

<?php
// PHP-Code, der nicht mehr funktioniert
function handler(Exception $e) { ... }
set_exception_handler('handler');

// PHP 5 und 7 kompatibel
function handler($e) { ... }

// Nur PHP 7
function handler(Throwable $e) { ... }
?>

Interne Konstruktoren lösen bei Fehlern immer Exceptions aus

Zuvor gaben einige interne Klassen null oder ein unbrauchbares Objekt zurück, wenn der Konstruktor fehlschlug. Alle internen Klassen lösen nun in einem solchen Fall eine Exception aus, so wie es die benutzerdefinierten Klassen bereits tun.

Parser-Fehler lösen ParseError aus

Parser-Fehler erzeugen nun ein ParseError-Objekt. Die Fehlerbehandlung für eval() sollte einen catch-Block enthalten, der diesen Fehler behandeln kann.

Änderungen des Schweregrads von E_STRICT-Meldungen

Alle E_STRICT-Meldungen wurden neu eingestuft. Die Konstante E_STRICT wurde beibehalten, sodass Aufrufe wie error_reporting(E_ALL|E_STRICT) keinen Fehler verursachen.

Änderungen des Schweregrads von E_STRICT-Meldungen
Situation Neue Stufe/Verhalten
Indizierung durch eine Ressource E_NOTICE
Abstrakte statische Methoden Hinweis entfernt, löst keinen Fehler aus
"Neudefinieren" eines Konstruktors Hinweis entfernt, löst keinen Fehler aus
Inkompatible Signaturen bei der Vererbung E_WARNING
Gleiche (kompatible) Eigenschaft in zwei verwendeten Traits Hinweis entfernt, löst keinen Fehler aus
Nicht-statischer Zugriff auf eine statische Eigenschaft E_NOTICE
Nur Variablen sollten per Referenz zugewiesen werden E_NOTICE
Nur Variablen sollten per Referenz übergeben werden E_NOTICE
Statischer Aufruf nicht-statischer Methoden E_DEPRECATED

Änderungen beim Umgang mit Variablen

PHP 7 verwendet nun beim Parsen von Quelldateien einen abstrakten Syntaxbaum. Dies hat viele Verbesserungen an der Sprache ermöglicht, die zuvor aufgrund der Einschränkungen des Parsers in früheren PHP-Versionen nicht möglich waren. Allerdings hat das auch dazu geführt, dass einige Spezialfälle aus Gründen der Konsistenz entfernt wurden, was Brüche in der Abwärtskompatibilität zur Folge hat. Diese Fälle werden in diesem Abschnitt detailliert beschrieben.

Änderungen beim Umgang mit indirekten Variablen, Eigenschaften und Methoden

Der indirekte Zugriff auf Variablen, Eigenschaften und Methoden wird nun in strikter Reihenfolge von links nach rechts ausgewertet. In früheren Versionen war die Reihenfolge der Auswertung in einigen Fällen umgekehrt. Die folgende Tabelle zeigt, wie sich die Reihenfolge der Auswertung geändert hat.

Alte und neue Auswertung indirekter Ausdrücke
Ausdruck Auswertung in PHP 5 Auswertung in PHP 7
$$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']()

Code, der die alte Auswertungsreihenfolge von rechts nach links verwendet, muss mit geschweiften Klammern umgeschrieben werden, um explizit diese Auswertungsreihenfolge zu verwenden (siehe die obige mittlere Spalte). Dadurch wird der Code sowohl vorwärtskompatibel mit PHP 7.x als auch rückwärtskompatibel mit PHP 5.x.

Dies betrifft auch das Schlüsselwort global. Falls erforderlich, kann die Syntax mit den geschweiften Klammern verwendet werden, um das frühere Verhalten zu emulieren:

<?php
function f() {
    
// Nur in PHP 5 gültig.
    
global $$foo->bar;

    
// In PHP 5 und 7 gültig.
    
global ${$foo->bar};
}
?>

Änderungen im Umgang mit der Funktion list()

list() weist Variablen nicht mehr in umgekehrter Reihenfolge zu

list() weist den Variablen nun Werte in der Reihenfolge zu, in der sie definiert sind, und nicht mehr in umgekehrter Reihenfolge. Wie unten gezeigt, betrifft dies im Allgemeinen nur Fälle, in denen list() in Verbindung mit dem Array-Operator [] verwendet wird:

<?php
list($a[], $a[], $a[]) = [123];
var_dump($a);
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 5:

array(3) {
  [0]=>
  int(3)
  [1]=>
  int(2)
  [2]=>
  int(1)
}

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 7:

array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}

Im Allgemeinen ist es nicht empfehlenswert, sich auf die Reihenfolge zu verlassen, in der die Zuweisungen mit list() erfolgen. Das ist ein Implementierungs-Detail, das sich in der Zukunft wieder ändern kann.

Leere list()-Zuweisungen wurden entfernt

list()-Konstrukte dürfen nicht mehr leer sein; die Folgenden sind nicht mehr erlaubt:

<?php
list() = $a;
list(,,) = 
$a;
list(
$x, list(), $y) = $a;
?>
list() kann keine Strings entpacken

list() kann Variablen vom Typ string nicht mehr entpacken. Stattdessen sollte str_split() verwendet werden.

Änderung der Reihenfolge von Array-Elementen, die automatisch durch Zuweisung per Referenz erzeugt werden

Die Reihenfolge der Elemente eines Arrays, die automatisch durch Zuweisung per Referenz erstellt werden, hat sich geändert. Zum Beispiel:

<?php
$array 
= [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 5:

array(2) {
  ["b"]=>
  &int(1)
  ["a"]=>
  &int(1)
}

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 7:

array(2) {
  ["a"]=>
  &int(1)
  ["b"]=>
  &int(1)
}

Klammern um Funktionsparameter haben keinen Einfluss mehr auf das Verhalten

Wenn in PHP 5 redundante Klammern um Funktionsparameter verwendet wurden, konnte die Warnung wegen strikter Standards unterdrückt werden, indem der Parameter per Referenz übergeben wurde. Nun wird die Warnung immer angezeigt.

<?php
function getArray() {
    return [
123];
}

function 
squareArray(array &$a) {
    foreach (
$a as &$v) {
        
$v **= 2;
    }
}

// Erzeugt in PHP 7 eine Warnung.
squareArray((getArray()));
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

Notice: Only variables should be passed by reference in /tmp/test.php on line 13

Änderungen bei foreach

Am Verhalten der Kontrollstruktur foreach wurden kleinere Änderungen vorgenommen, die sich vor allem auf die Handhabung des internen Array-Zeigers und auf die Änderung des Arrays, über das iteriert wird, beziehen.

foreach ändert den internen Array-Zeiger nicht mehr

Vor PHP 7 wurde der interne Array-Zeiger verändert, während mit foreach über ein Array iteriert wurde. Dies ist nun, wie im folgenden Beispiel gezeigt wird, nicht mehr der Fall:

<?php
$array 
= [012];
foreach (
$array as &$val) {
    
var_dump(current($array));
}
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 5:

int(1)
int(2)
bool(false)

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 7:

int(0)
int(0)
int(0)

foreach iteriert bei Übergabe per Wert über eine Kopie des Arrays

Wenn foreach im Standardmodus Pass-by-Value verwendet wird, arbeitet es nun mit einer Kopie des Arrays, über das iteriert wird, und nicht mit dem Array selbst. Das bedeutet, dass Änderungen, die während des Iterierens am Array vorgenommen werden, keine Auswirkungen auf die iterierten Werte haben.

Verbessertes Iterationsverhalten von foreach bei Übergabe per Referenz

Bei der Iteration per Referenz kann foreach Änderungen, die während des Iterierens am Array vorgenommen werden, nun besser verfolgen. Wenn zum Beispiel während des Iterierens etwas an das Array angehängt wird, führt das dazu, dass nun auch über die angehängten Werte iteriert wird:

<?php
$array 
= [0];
foreach (
$array as &$val) {
    
var_dump($val);
    
$array[1] = 1;
}
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 5:

int(0)

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 7:

int(0)
int(1)

Iteration über nicht-Traversable Objekte

Die Iteration über Objekte, die Traversable nicht implementieren, verhält sich nun genauso wie die Iteration über Arrays per Referenz. Dies führt dazu, dass das verbesserte Verhalten, wenn sich ein Array während des Iterierens ändert auch angewendet wird, wenn Eigenschaften zum Objekt hinzugefügt oder daraus entfernt werden.

Änderungen im Umgang mit dem Typ int

Ungültige oktale Literale

Bisher wurden oktale Literale, die ungültige Zahlen enthielten, stillschweigend abgeschnitten (0128 wurde als 012 interpretiert). Nun verursacht ein ungültiges Oktal-Literal einen Parser-Fehler.

Negative Bitverschiebungen

Bitweises Verschieben um negative Zahlen führt nun zu einem ArithmeticError:

<?php
var_dump
(>> -1);
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 5:

int(0)

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 7:

Fatal error: Uncaught ArithmeticError: Bit shift by negative number in /tmp/test.php:2
Stack trace:
#0 {main}
  thrown in /tmp/test.php on line 2

Bitverschiebungen außerhalb des zulässigen Bereichs

Bitweise Verschiebungen (in beide Richtungen) über die Bitbreite eines int ergeben immer 0. Bisher war das Verhalten solcher Verschiebungen von der Architektur abhängig.

Änderungen bei der Division durch Null

Wenn 0 beim Divisionsoperator (/) oder beim Modulusoperator (%) als Divisor verwendet wird, wurde bisher einen Fehler der Stufe E_WARNING ausgegeben und false zurückgegeben. Nun gibt der Divisionsoperator, wie in IEEE 754 festgelegt, eine Gleitkommazahl entweder als +INF, -INF oder NAN zurück. Der Modulusoperator gibt nun kein E_WARNING mehr aus, sondern löst stattdessen eine DivisionByZeroError-Exception aus.

<?php
var_dump
(3/0);
var_dump(0/0);
var_dump(0%0);
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 5:

Warning: Division by zero in %s on line %d
bool(false)

Warning: Division by zero in %s on line %d
bool(false)

Warning: Division by zero in %s on line %d
bool(false)

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 7:

Warning: Division by zero in %s on line %d
float(INF)

Warning: Division by zero in %s on line %d
float(NAN)

PHP Fatal error:  Uncaught DivisionByZeroError: Modulo by zero in %s line %d

Änderungen im Umgang mit dem Typ string

Hexadezimale Zeichenketten werden nicht mehr als numerisch betrachtet

Zeichenketten, die hexadezimale Zahlen enthalten, gelten nicht mehr als numerisch. Zum Beispiel:

<?php
var_dump
("0x123" == "291");
var_dump(is_numeric("0x123"));
var_dump("0xe" "0x1");
var_dump(substr("foo""0x1"));
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 5:

bool(true)
bool(true)
int(15)
string(2) "oo"

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 7:

bool(false)
bool(false)
int(0)

Notice: A non well formed numeric value encountered in /tmp/test.php on line 5
string(3) "foo"

filter_var() kann verwendet werden, um zu prüfen, ob ein string eine hexadezimale Zahl enthält, und auch zur Umwandlung einer Zeichenkette dieses Typs zu einem int:

<?php
$str 
"0xffff";
$int filter_var($strFILTER_VALIDATE_INTFILTER_FLAG_ALLOW_HEX);
if (
false === $int) {
    throw new 
Exception("Ungültige Ganzzahl!");
}
var_dump($int); // int(65535)
?>

\u{ kann zu Fehlern führen

Mit der Einführung der neuen Unicode-Codepoint-Maskierungssyntax verursachen Zeichenketten, die \u{ gefolgt von einer ungültigen Sequenz enthalten, einen fatalen Fehler. Um dies zu vermeiden, sollte der führende Rückwärtsstrich maskiert werden.

Entfernte Funktionen

call_user_method() und call_user_method_array()

Diese Funktionen sind seit PHP 4.1.0 zugunsten von call_user_func() und call_user_func_array() veraltet. Alternativ dazu können auch die Variablenfunktionen und/oder der Operator ... verwendet werden.

Alle ereg*-Funktionen

Alle ereg-Funktionen wurden entfernt. Es wird empfohlen, stattdessen PCRE zu verwenden.

Aliase bei mcrypt

Die veraltete Funktion mcrypt_generic_end() wurde zugunsten von mcrypt_generic_deinit() entfernt.

Darüber hinaus wurden die veralteten Funktionen mcrypt_ecb() mcrypt_cbc(), mcrypt_cfb() und mcrypt_ofb() zugunsten von mcrypt_decrypt() in Kombination mit der entsprechenden MCRYPT_MODE_*-Konstante entfernt.

Alle ext/mysql-Funktionen

Alle ext/mysql-Funktionen wurden entfernt. Details zur Auswahl einer anderen MySQL-API sind unter Auswahl einer API zu finden.

Alle ext/mssql-Funktionen

Alle ext/mssql-Funktionen wurden entfernt.

Aliase bei intl

Die veralteten Aliase datefmt_set_timezone_id() und IntlDateFormatter::setTimeZoneID() wurden zugunsten von datefmt_set_timezone() bzw. IntlDateFormatter::setTimeZone() entfernt.

set_magic_quotes_runtime()

Die Funktion set_magic_quotes_runtime() und ihr Alias magic_quotes_runtime() wurden entfernt. Sie sind seit PHP 5.3.0 veraltet und praktisch nutzlos, seit in PHP 5.4.0 die magischen Anführungszeichen entfernt wurden.

set_socket_blocking()

Der veraltete Alias set_socket_blocking() wurde zugunsten von stream_set_blocking() entfernt.

dl() in PHP-FPM

Die Funktion dl() kann in PHP-FPM nicht mehr verwendet werden. In CLI und integrierten SAPIs ist sie weiterhin verfügbar.

GD-Type1-Funktionen

Die PostScript-Type1-Schriftarten werden von der Erweiterung GD nicht mehr unterstützt. Infolgedessen wurden die folgenden Funktionen entfernt:

  • imagepsbbox()
  • imagepsencodefont()
  • imagepsextendfont()
  • imagepsfreefont()
  • imagepsloadfont()
  • imagepsslantfont()
  • imagepstext()

Es wird empfohlen, stattdessen die TrueType-Schriftarten und die damit verbundenen Funktionen zu verwenden.

Entfernte INI-Direktiven

Entfernte Features

Die folgenden INI-Direktiven wurden entfernt, da ihre zugehörigen Funktionen ebenfalls entfernt wurden:

  • always_populate_raw_post_data
  • asp_tags

xsl.security_prefs

Die Direktive xsl.security_prefs wurde entfernt. Stattdessen sollte die Methode XsltProcessor::setSecurityPrefs() aufgerufen werden, um die Sicherheitseinstellungen auf Basis einzelner Prozessoren zu steuern.

Andere nicht abwärtskompatible Änderungen

Neue Objekte können nicht per Referenz zugewiesen werden

Es ist nicht mehr möglich, das Resultat einer new-Anweisung per Referenz einer Variablen zuzuweisen:

<?php
class {}
$c =& new C;
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 5:

Deprecated: Assigning the return value of new by reference is deprecated in /tmp/test.php on line 3

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 7:

Parse error: syntax error, unexpected 'new' (T_NEW) in /tmp/test.php on line 3

Ungültige Klassen-, Schnittstellen- und Traitnamen

Die folgenden Namen können nicht mehr zur Benennung von Klassen, Schnittstellen und Traits verwendet werden:

  • bool
  • int
  • float
  • string
  • null
  • true
  • false

Darüber hinaus sollten auch die folgenden Namen nicht verwendet werden. Auch wenn sie in PHP 7.0 keinen Fehler erzeugen, sind sie für die zukünftige Verwendung reserviert und sollten als veraltet angesehen werden.

  • resource
  • object
  • mixed
  • numeric

ASP- und Skript-Tags wurden entfernt

Es ist nicht mehr möglich, ASP-ähnliche Tags oder Skript-Tags zu verwenden, um PHP-Code einzuschließen. Die folgenden Tags sind hiervon betroffen:

Entfernte ASP- und Skript-Tags
Öffnendes Tag Schließendes Tag
<% %>
<%= %>
<script language="php"> </script>

Aufrufe aus inkompatiblen Kontexten wurden entfernt

Ein statischer Aufruf einer nicht-statischen Methode aus einem inkompatiblen Kontext war bereits in PHP 5.6 veraltet und führt nun dazu, dass die aufgerufene Methode eine undefinierte $this-Variable hat und einen Veraltet-Hinweis ausgibt.

<?php
class {
    public function 
test() { var_dump($this); }
}

// Hinweis: Erweitert A NICHT
class {
    public function 
callNonStaticMethodOfA() { A::test(); }
}

(new 
B)->callNonStaticMethodOfA();
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 5.6:

Deprecated: Non-static method A::test() should not be called statically, assuming $this from incompatible context in /tmp/test.php on line 8
object(B)#1 (0) {
}

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 7:

Deprecated: Non-static method A::test() should not be called statically in /tmp/test.php on line 8

Notice: Undefined variable: this in /tmp/test.php on line 3
NULL

yield ist nun ein rechtsassoziativer Operator

Das yield-Konstrukt ist nun rechtsassoziativ (Auswertung von rechts nach links) und es werden keine Klammern mehr benötigt. In der Rangfolge liegt es nun zwischen print und =>. Dadurch ändert sich das Verhalten wie folgt:

<?php
echo yield -1;
// Wurde zuvor interpretiert als
echo (yield) - 1;
// Und wird nun interpretiert als
echo yield (-1);

yield 
$foo or die;
// Wurde zuvor interpretiert als
yield ($foo or die);
// Und wird nun interpretiert als
(yield $foo) or die;
?>

Um Unklarheiten zu beseitigen, können Klammern verwendet werden.

Eine Funktion kann nicht mehrere Parameter mit demselben Namen haben

Es ist nicht mehr möglich, in einer Funktion mehrere Parameter mit demselben Namen zu definieren. Zum Beispiel führt eine Funktion wie die folgende zu einem E_COMPILE_ERROR:

<?php
function foo($a$b$unused$unused) {
    
//
}
?>

Funktionen, die Parameter analysieren, melden den aktuellen Parameterwert

Die Funktionen func_get_arg(), func_get_args() und debug_backtrace() und Backtraces bei Exceptions melden nicht mehr den ursprünglichen Wert, der an einen Parameter übergeben wurde, sondern stattdessen den aktuellen Wert (der möglicherweise geändert wurde).

<?php
function foo($x) {
    
$x++;
    
var_dump(func_get_arg(0));
}
foo(1);?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 5:

1

Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 7:

2

Switch-Anweisungen können nicht mehrere default-Blöcke haben

Es ist nicht mehr möglich, zwei oder mehr default-Blöcke in einer switch-Anweisung zu definieren. Zum Beispiel löst die folgende switch-Anweisung einen E_COMPILE_ERROR aus:

<?php
switch (1) {
    default:
    break;
    default:
    break;
}
?>

$HTTP_RAW_POST_DATA wurde entfernt

$HTTP_RAW_POST_DATA ist nicht mehr verfügbar. Stattdessen sollte der php://input-Stream verwendet werden.

In INI-Dateien wurden Kommentare im #-Format entfernt

In INI-Dateien ist es nicht mehr möglich, Kommentare durch ein vorangestelltes # zu markieren. Stattdessen sollte ein ; (Semikolon) verwendet werden. Diese Änderung gilt nicht nur für die php.ini, sondern auch für Dateien, die von parse_ini_file() und parse_ini_string() verarbeitet werden.

Erweiterung JSON durch JSOND ersetzt

Die Erweiterung JSON wurde durch JSOND ersetzt, was zu drei kleineren Beeinträchtigungen in der Abwärtskompatibilität führt. Erstens darf eine Zahl nicht mit einem Dezimalpunkt enden (d. h. 34. muss entweder durch 34.0 oder 34 ersetzt werden). Zweitens darf bei Verwendung der wissenschaftlichen Notation der Exponent e nicht unmittelbar auf einen Dezimalpunkt folgen (d. h. 3.e3 muss entweder durch 3.0e3 oder 3e3 ersetzt werden). Und schließlich wird eine leere Zeichenkette nicht mehr als gültiges JSON angesehen.

Interne Funktionen schlagen bei Überlauf fehl

Bisher haben interne Funktionen Zahlen, die von Gleitkommazahlen in Ganzzahlen umgewandelt wurden, stillschweigend abgeschnitten, wenn die Gleitkommazahl zu groß war, um sie als Ganzzahl darzustellen. Nun wird ein Fehler der Stufe E_WARNING ausgegeben und null zurückgegeben.

Korrekturen bei Rückgabewerten von benutzerdefinierten Session-Handlern

Eine Prädikatsfunktion, die von einem benutzerdefinierten Session-Handler implementiert wird und entweder false oder -1 zurückgibt, löst einen schwerwiegenden Fehler aus. Ist ein von dieser Funktion zurückgegebener Wert nicht boolesch, -1 oder 0, schlägt die Funktion fehl und löst einen Fehler der Stufe E_WARNING aus.

Sortierreihenfolge gleichwertiger Elemente

Aufgrund von Verbesserungen des internen Sortieralgorithmus kann sich die Sortierreihenfolge von Elementen, die beim Vergleich als gleichwertig betrachtet werden, im Vergleich zu vorherigen Versionen ändern.

Hinweis:

Es wird davon abgeraten, sich auf die Reihenfolge der Elemente, die als gleichwertig betrachtet werden, zu verlassen; sie kann sich jederzeit ändern.

Falsch platzierte break- und continue-Anweisungen

break- und continue-Anweisungen außerhalb einer Schleife oder einer switch-Kontrollstruktur werden nun bei der Kompilierung erkannt, anstatt wie bisher zur Laufzeit, und lösen einen Fehler der Stufe E_COMPILE_ERROR aus.

Mhash ist keine Erweiterung mehr

Die Erweiterung Mhash wurde vollständig in die Erweiterung Hash integriert. Daher ist es nicht mehr möglich, mit extension_loaded() zu erkennen, ob Mhash unterstützt wird. Stattdessen sollte function_exists() verwendet werden. Darüber hinaus wird Mhash nicht mehr von get_loaded_extensions() und ähnlichen Funktionen gemeldet.

declare(ticks)

Die Directive declare(ticks) wird nicht mehr in verschiedene Kompilierungseinheiten übertragen.

add a note add a note

User Contributed Notes 10 notes

up
181
me at fquff dot io
6 years ago
[Editor's note: fixed limit on user request]

As a mathematician, 3/0 == +INF IS JUST WRONG. You can't just assume 3/0 == lim_{x->0+} 3/x, which is +INF indeed, because division IS NOT A CONTINUOUS FUNCTION in x == 0.

Also, 3/0 == +INF ("positive" infinity) while -3/0 == -INF ("negative" infinity) requires the assumption that 0 is a positive number, which is just as illogical as it looks like.

The fact that a warning is emitted is good, but it should definitely equals to NaN. ±INF is just illogical (and arithmetically wrong).

Except for this "detail", looks an amazing update, can't wait to test it even further!

Cheers,
P.
up
103
mossy2100
6 years ago
Although $x/0 is technically not infinity in a purely mathematical sense, when you understand why the IEEE float includes a value for infinity, and returns infinity in this case, it makes sense that PHP would agree with this.

The reason is that programmers don't usually divide by 0 on purpose. A value of 0 as a divisor usually occurs due to underflow, i.e. a value which is too small to be represented as a float. So, for example, if you have values like:
$x = 1;
$y = 1e-15 * 1e-15;
$z = $x/$y;
Because $y will have underflowed to 0, the division operation will throw the division by zero warning, and $z will be set to INF. In a better computer, however, $y would not have the value 0 (it would be 1e-30) and $z would not have the value INF (it would be 1e30).

In other words, 0 is not only representative of an actual 0, but also a very small number which float cannot represent correctly (underflow), and INF does not only represent infinity, but also a very big number which float cannot represent correctly (overflow). We do the best we can within the limitations of floating point values, which are really just good approximations of the actual numbers being represented.

What does bother me is that division by zero is handled in two different ways depending on the operator. I would have preferred the new DivisionByZeroError exception to be thrown in all cases, for consistency and to enforce good programming practices.
up
126
tuxedobob
6 years ago
As a programmer, I don't care whether 3/0 is INF or NaN. Both answers are (probably) equally useless, and tell me that something somewhere else is screwed up.
up
17
tkondrashov at gmail dot com
3 years ago
split() was also removed in 7.0, so be sure to check your old code for it as well as the functions listed in this doc
up
7
maba at mb-systemhaus dot net
6 years ago
NOTE:
the new variable handling in PHP 7 also has side effects on the COM .NET extension. Numeric variants (in the Windows application space) now must be quoted when passed over from PHP. This is the case when the receiving application expects a variable of type variant.

Here is an example:

<?php
  $word
= new COM('Word.Application');

 
// now load a document, ...

  // the following works in PHP 5 but will throw an exception in PHP 7
 
$word->ActiveDocument->PrintOut(false, false, 0, $outfile);

 
// the following works in PHP 7 as well, please note the quotes around the '0'
 
$word->ActiveDocument->PrintOut(false, false, '0', $outfile);
?>
up
12
Frank
6 years ago
[Editor's Note: that change is listed in the "Changed functions" section.]

The substr function has also been changed in a backward incompatible way.

<?php
substr
("test",4);  # false in PHP 5,  "" in PHP 7
?>

In fact, this is the only thing we had to change in a number of places for our code base to run on PHP 7. It's definitely an improvement though, as the old behavior tended to cause bugs in border cases.
up
1
ilya dot chase at yandex dot ru
3 years ago
Take note that in preg_replace() function, flag '\e' was deleted in PHP 7.0.0. This function will return null always with this flag. Doc: https://www.php.net/manual/ru/function.preg-replace.php
up
0
viktor dot csiky at nospam dot nospam dot eu
6 years ago
It is stated:

"foreach by-value operates on a copy of the array

When used in the default by-value mode, foreach will now operate on a copy of the array being iterated rather than the array itself. This means that changes to the array made during iteration will not affect the values that are iterated."

Please note that this is not exactly true. New foreach operates on a copy of the array, by-value or by-reference. It seems that in the latter case, the array copy is simply moved over (to) the original array before it is presumably destroyed.

As a consequence of this, you may not "dereference" an array containing values - e.g. for use with ReflectionMethod::invokeArgs() or the good ole' call_user_func().
Consider the snippet below:

<?php
function deref(Array $inputArray)
{
       
$retVal = [];
       
        foreach (
$inputArray as &$inputValue)
        {
           
$retVal[] = $inputValue;
        }

        return
$retVal;
}
?>

As of PHP 7.0, this *will no longer work*. You will get the usual suspect:

PHP Warning:  Parameter n to whatever() expected to be a reference, value given in baz.php on line x

You need to convert it to explicitly reference the original array:
<?php
function deref(Array $inputArray)
{
       
$retVal = [];
       
        foreach (
$inputArray as $inputKey => $inputValue)
        {
           
$retVal[$inputKey] = &$inputArray[$inputKey];
        }

        return
$retVal;
}
?>

PLEASE NOTE that this might have the unforeseen consequence of your code not working anymore in php versions less than 5.3 (that is, 5.2 and below).
up
-12
Ray.Paseur sometimes uses Gmail
5 years ago
In the section captioned "Changes to the handling of indirect variables, properties, and methods" there are parentheses used in the table directly beneath "PHP 7 interpretation." 

The parentheses are intended to show the evaluation order, but they are not part of the syntax, and should not be used in the variable definition or reference.  This juxtaposition confused one of my colleagues; hopefully this note will save someone else some time.

Examples of the correct curly-brace syntax is further down the page, in the section captioned "global only accepts simple variables."
To Top