Modifications entrainant une incompatibilité ascendante
Changes to error and exception handling
Many fatal and recoverable fatal errors have been converted to exceptions in PHP 7. These error exceptions inherit from the Error class, which itself implements the Throwable interface (the new base interface all exceptions inherit).
This means that custom error handlers may no longer be triggered because exceptions may be thrown instead (causing new fatal errors for uncaught Error exceptions).
A fuller description of how errors operate in PHP 7 can be found on the PHP 7 errors page. This migration guide will merely enumerate the changes that affect backward compatibility.
set_exception_handler() is no longer guaranteed to receive Exception objects
Code that implements an exception handler registered with set_exception_handler() using a type declaration of Exception will cause a fatal error when an Error object is thrown.
If the handler needs to work on both PHP 5 and 7, you should remove the type declaration from the handler, while code that is being migrated to work on PHP 7 exclusively can simply replace the Exception type declaration with Throwable instead.
<?php
// PHP 5 era code that will break.
function handler(Exception $e) { ... }
set_exception_handler('handler');
// PHP 5 and 7 compatible.
function handler($e) { ... }
// PHP 7 only.
function handler(Throwable $e) { ... }
?>
Internal constructors always throw exceptions on failure
Previously, some internal classes would return NULL
or an unusable object
when the constructor failed. All internal classes will now throw an
Exception in this case in the same way that user
classes already had to.
Parse errors throw ParseError
Parser errors now throw a ParseError object. Error handling for eval() should now include a catch block that can handle this error.
E_STRICT notices severity changes
All of the E_STRICT
notices have been reclassified to
other levels. E_STRICT
constant is retained, so calls like
error_reporting(E_ALL|E_STRICT) will not cause an error.
Situation | New level/behaviour |
---|---|
Indexing by a resource | E_NOTICE |
Abstract static methods | Notice removed, triggers no error |
"Redefining" a constructor | Notice removed, triggers no error |
Signature mismatch during inheritance | E_WARNING |
Same (compatible) property in two used traits | Notice removed, triggers no error |
Accessing static property non-statically | E_NOTICE |
Only variables should be assigned by reference | E_NOTICE |
Only variables should be passed by reference | E_NOTICE |
Calling non-static methods statically | E_DEPRECATED |
Changes to variable handling
PHP 7 now uses an abstract syntax tree when parsing source files. This has permitted many improvements to the language which were previously impossible due to limitations in the parser used in earlier versions of PHP, but has resulted in the removal of a few special cases for consistency reasons, which has resulted in backward compatibility breaks. These cases are detailed in this section.
Changes to the handling of indirect variables, properties, and methods
Indirect access to variables, properties, and methods will now be evaluated strictly in left-to-right order, as opposed to the previous mix of special cases. The table below shows how the order of evaluation has changed.
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']()
|
Code that used the old right-to-left evaluation order must be rewritten to explicitly use that evaluation order with curly braces (see the above middle column). This will make the code both forwards compatible with PHP 7.x and backwards compatible with PHP 5.x.
This also affects the global keyword. The curly brace syntax can be used to emulate the previous behaviour if required:
<?php
function f() {
// Valid in PHP 5 only.
global $$foo->bar;
// Valid in PHP 5 and 7.
global ${$foo->bar};
}
?>
Changes to list() handling
list() no longer assigns variables in reverse order
list() will now assign values to variables in the
order they are defined, rather than reverse order. In general, this only
affects the case where list() is being used in
conjunction with the array []
operator, as shown below:
<?php
list($a[], $a[], $a[]) = [1, 2, 3];
var_dump($a);
?>
Résultat de l'exemple ci-dessus en PHP 5 :
array(3) { [0]=> int(3) [1]=> int(2) [2]=> int(1) }
Résultat de l'exemple ci-dessus en PHP 7 :
array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }
In general, it is recommended not to rely on the order in which list() assignments occur, as this is an implementation detail that may change again in the future.
Empty list() assignments have been removed
list() constructs can no longer be empty. The following are no longer allowed:
<?php
list() = $a;
list(,,) = $a;
list($x, list(), $y) = $a;
?>
list() cannot unpack strings
list() can no longer unpack string variables. str_split() should be used instead.
Array ordering when elements are automatically created during by reference assignments has changed
The order of the elements in an array has changed when those elements have been automatically created by referencing them in a by reference assignment. For example:
<?php
$array = [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
?>
Résultat de l'exemple ci-dessus en PHP 5 :
array(2) { ["b"]=> &int(1) ["a"]=> &int(1) }
Résultat de l'exemple ci-dessus en PHP 7 :
array(2) { ["a"]=> &int(1) ["b"]=> &int(1) }
Parentheses around function arguments no longer affect behaviour
In PHP 5, using redundant parentheses around a function argument could quiet strict standards warnings when the function argument was passed by reference. The warning will now always be issued.
<?php
function getArray() {
return [1, 2, 3];
}
function squareArray(array &$a) {
foreach ($a as &$v) {
$v **= 2;
}
}
// Generates a warning in PHP 7.
squareArray((getArray()));
?>
L'exemple ci-dessus va afficher :
Notice: Only variables should be passed by reference in /tmp/test.php on line 13
Changements concernant foreach
Des changements mineurs ont été faits sur le comportement de la structure de contrôle foreach, principalement sur la gestion du pointeur interne de tableau et la modification du tableau étant parcouru.
foreach ne modifie plus le pointeur interne de tableau
Avant PHP 7, le pointeur interne de tableau était modifié pendant que l'on parcourait un tableau avec foreach. Cela n'est plus le cas, comme le montre l'exemple suivant :
<?php
$array = [0, 1, 2];
foreach ($array as &$val) {
var_dump(current($array));
}
?>
Résultat de l'exemple ci-dessus en PHP 5 :
int(1) int(2) bool(false)
Résultat de l'exemple ci-dessus en PHP 7 :
int(0) int(0) int(0)
foreach par valeur travaille sur une copie du tableau
Lors de l'utilisation du mode par défaut (par valeur), foreach travaille maintenant sur une copie du tableau en cours parcouru plutôt que sur le tableau lui-même. Cela signifie que les changements réalisés sur le tableau pendant son parcours n'affecteront pas les valeurs qui sont parcourues.
Le comportement du parcours de foreach par référence a été amélioré
Lors du parcours d'un tableau par référence, foreach identifie mieux les changements faits au tableau pendant son parcours. Par exemple, si des valeurs sont ajoutées à un tableau pendant son parcours, alors ces nouvelles valeurs seront également parcourues :
<?php
$array = [0];
foreach ($array as &$val) {
var_dump($val);
$array[1] = 1;
}
?>
Résultat de l'exemple ci-dessus en PHP 5 :
int(0)
Résultat de l'exemple ci-dessus en PHP 7 :
int(0) int(1)
Parcours d'objets non-Traversable
Le parcours d'un objet non-Traversable est maintenant identique au parcours d'un tableau par référence. En conséquence l'amélioration du comportement lors de la modification d'un tableau pendant son parcours est également appliquée lorsque des propriétés sont ajoutées ou supprimées d'un objet.
Changes to integer handling
Invalid octal literals
Previously, octal literals that contained invalid numbers were silently truncated (0128 was taken as 012). Now, an invalid octal literal will cause a parse error.
Negative bitshifts
Bitwise shifts by negative numbers will now throw an ArithmeticError:
<?php
var_dump(1 >> -1);
?>
Résultat de l'exemple ci-dessus en PHP 5 :
int(0)
Résultat de l'exemple ci-dessus en 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
Out of range bitshifts
Bitwise shifts (in either direction) beyond the bit width of an integer will always result in 0. Previously, the behaviour of such shifts was architecture dependent.
Changes to Division By Zero
Previously, when 0 was used as the divisor for either the divide (/) or
modulus (%) operators, an E_WARNING would be emitted and
false
would be returned. Now, the divide operator
returns a float as either +INF, -INF, or NAN, as specified by IEEE 754. The modulus operator E_WARNING
has been removed and will throw a DivisionByZeroError
exception.
<?php
var_dump(3/0);
var_dump(0/0);
var_dump(0%0);
?>
Résultat de l'exemple ci-dessus en 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)
Résultat de l'exemple ci-dessus en 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
Changes to string handling
Hexadecimal strings are no longer considered numeric
Strings containing hexadecimal numbers are no longer considered to be numeric. For example:
<?php
var_dump("0x123" == "291");
var_dump(is_numeric("0x123"));
var_dump("0xe" + "0x1");
var_dump(substr("foo", "0x1"));
?>
Résultat de l'exemple ci-dessus en PHP 5 :
bool(true) bool(true) int(15) string(2) "oo"
Résultat de l'exemple ci-dessus en 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() can be used to check if a string contains a hexadecimal number, and also to convert a string of that type to an integer:
<?php
$str = "0xffff";
$int = filter_var($str, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX);
if (false === $int) {
throw new Exception("Invalid integer!");
}
var_dump($int); // int(65535)
?>
\u{ may cause errors
Due to the addition of the new Unicode codepoint escape syntax, strings containing a literal \u{ followed by an invalid sequence will cause a fatal error. To avoid this, the leading backslash should be escaped.
Fonctions supprimées
call_user_method() et call_user_method_array()
Ces fonctions sont obsolètes dans PHP 4.1.0, et remplacées par call_user_func() et call_user_func_array(). Vous pourriez également utiliser les fonctions variables et/ou l'opérateur ....
Toutes les fonctions ereg*
Toutes les fonctions ereg ont été supprimées. PCRE est une alternative recommandée.
Aliasmcrypt
La fonction obsolète mcrypt_generic_end() a été remplacée par mcrypt_generic_deinit().
De plus, les fonctions obsolètes mcrypt_ecb(),
mcrypt_cbc(), mcrypt_cfb() et
mcrypt_ofb() ont été remplacées par l'utilisation de
mcrypt_decrypt() avec la constante appropriée
MCRYPT_MODE_*
.
Toutes les fonctions ext/mysql
Toutes les fonctions ext/mysql ont été supprimées. Pour plus d'informations sur le choix d'une autre API MySQL, consultez choisir une API MySQL.
Toutes les fonctions ext/mssql
Toutes les fonctions ext/mssql ont été supprimées. Pour obtenir une liste des alternatives, consultez l' introduction MSSQL.
intl aliases
Les alias obsolètes datefmt_set_timezone_id() et IntlDateFormatter::setTimeZoneID() ont été supprimés et remplacés respectivement par datefmt_set_timezone() et IntlDateFormatter::setTimeZone().
set_magic_quotes_runtime()
Les fonctions set_magic_quotes_runtime(), ainsi que son alias magic_quotes_runtime(), ont été supprimés. Ils étaient obsolètes depuis PHP 5.3.0, et sans effet depuis la suppression des guillemets magiques en PHP 5.4.0.
set_socket_blocking()
L'alias obsolète set_socket_blocking() a été supprimé et remplacé par stream_set_blocking().
dl() avec PHP-FPM
dl() ne peut plus être utilisé avec PHP-FPM. Il continue à fonctionner dans les SAPIs CLI et Embed.
Fonctions GD Type1
Le support des polices PostScript Type1 a été supprimé de l'extension GD, entraînant la suppression des fonctions suivantes :
- imagepsbbox()
- imagepsencodefont()
- imagepsextendfont()
- imagepsfreefont()
- imagepsloadfont()
- imagepsslantfont()
- imagepstext()
A la place, il est recommandé d'utiliser les polices TrueType et leurs fonctions associées.
Removed INI directives
Removed features
The following INI directives have been removed as their associated features have also been removed:
xsl.security_prefs
The xsl.security_prefs
directive has been removed.
Instead, the XsltProcessor::setSecurityPrefs()
method should be called to control the security preferences on a
per-processor basis.
Other backward incompatible changes
New objects cannot be assigned by reference
The result of the new statement can no longer be assigned to a variable by reference:
<?php
class C {}
$c =& new C;
?>
Résultat de l'exemple ci-dessus en PHP 5 :
Deprecated: Assigning the return value of new by reference is deprecated in /tmp/test.php on line 3
Résultat de l'exemple ci-dessus en PHP 7 :
Parse error: syntax error, unexpected 'new' (T_NEW) in /tmp/test.php on line 3
Invalid class, interface and trait names
The following names cannot be used to name classes, interfaces or traits:
Furthermore, the following names should not be used. Although they will not generate an error in PHP 7.0, they are reserved for future use and should be considered deprecated.
ASP and script PHP tags removed
Support for using ASP and script tags to delimit PHP code has been removed. The affected tags are:
Opening tag | Closing tag |
---|---|
<% |
%> |
<%= |
%> |
<script language="php"> |
</script> |
Calls from incompatible context removed
Previously deprecated in PHP 5.6, static calls made to a non-static method with an incompatible context will now result in the called method having an undefined $this variable and a deprecation warning being issued.
<?php
class A {
public function test() { var_dump($this); }
}
// Note: Does NOT extend A
class B {
public function callNonStaticMethodOfA() { A::test(); }
}
(new B)->callNonStaticMethodOfA();
?>
Résultat de l'exemple ci-dessus en 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) { }
Résultat de l'exemple ci-dessus en 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 is now a right associative operator
The yield construct no longer requires parentheses, and has been changed to a right associative operator with precedence between print and =>. This can result in changed behaviour:
<?php
echo yield -1;
// Was previously interpreted as
echo (yield) - 1;
// And is now interpreted as
echo yield (-1);
yield $foo or die;
// Was previously interpreted as
yield ($foo or die);
// And is now interpreted as
(yield $foo) or die;
?>
Parentheses can be used to disambiguate those cases.
Functions cannot have multiple parameters with the same name
It is no longer possible to define two or more function parameters with the
same name. For example, the following function will trigger an
E_COMPILE_ERROR
:
<?php
function foo($a, $b, $unused, $unused) {
//
}
?>
Functions inspecting arguments report the current parameter value
func_get_arg(), func_get_args(), debug_backtrace() and exception backtraces will no longer report the original value that was passed to a parameter, but will instead provide the current value (which might have been modified).
<?php
function foo($x) {
$x++;
var_dump(func_get_arg(0));
}
foo(1);?>
Résultat de l'exemple ci-dessus en PHP 5 :
1
Résultat de l'exemple ci-dessus en PHP 7 :
2
Switch statements cannot have multiple default blocks
It is no longer possible to define two or more default blocks in a switch
statement. For example, the following switch statement will trigger an
E_COMPILE_ERROR
:
<?php
switch (1) {
default:
break;
default:
break;
}
?>
$HTTP_RAW_POST_DATA removed
$HTTP_RAW_POST_DATA is no longer available. The php://input stream should be used instead.
# comments in INI files removed
Support for prefixing comments with # in INI files has been removed. ; (semi-colon) should be used instead. This change applies to php.ini, as well as files handled by parse_ini_file() and parse_ini_string().
JSON extension replaced with JSOND
The JSON extension has been replaced with JSOND, causing three minor BC breaks. Firstly, a number must not end in a decimal point (i.e. 34. must be changed to either 34.0 or 34). Secondly, when using scientific notation, the e exponent must not immediately follow a decimal point (i.e. 3.e3 must be changed to either 3.0e3 or 3e3). Finally, an empty string is no longer considered valid JSON.
Internal function failure on overflow
Previously, internal functions would silently truncate numbers produced from
float-to-integer coercions when the float was too large to represent as an
integer. Now, an E_WARNING will be emitted and NULL
will be returned.
Fixes to custom session handler return values
Any predicate functions implemented by custom session handlers that return
either FALSE
or -1 will be fatal errors. If any value
from these functions other than a boolean, -1, or
0 is returned, then it will fail and an E_WARNING will be
emitted.
Sort order of equal elements
The internal sorting algorithm has been improved, what may result in different sort order of elements, which compare as equal, than before.
Note:
Don't rely on the order of elements which compare as equal; it might change anytime.
Misplaced break and switch statements
break and continue statements outside of
a loop or switch control structure are now detected at
compile-time instead of run-time as before, and trigger an
E_COMPILE_ERROR
.
Mhash is not an extension anymore
The Mhash extension has been fully integrated into the Hash extension. Therefore, it is no longer possible to detect Mhash support with extension_loaded(); use function_exists() instead. Furthermore, Mhash is no longer reported by get_loaded_extensions() and related features.
Version en cache
05/11/2024 14:52:31 Cette version de la page est en cache (à la date du 05/11/2024 14:52:31) afin d'accélérer le traitement. Vous pouvez activer le mode utilisateur dans le menu en haut pour afficher la dernère version de la page.Document créé le 30/01/2003, dernière modification le 26/10/2018
Source du document imprimé : https://www.gaudry.be/php-rf-migration70.incompatible.html
L'infobrol est un site personnel dont le contenu n'engage que moi. Le texte est mis à disposition sous licence CreativeCommons(BY-NC-SA). Plus d'info sur les conditions d'utilisation et sur l'auteur.
Références
Ces références et liens indiquent des documents consultés lors de la rédaction de cette page, ou qui peuvent apporter un complément d'information, mais les auteurs de ces sources ne peuvent être tenus responsables du contenu de cette page.
L'auteur de ce site est seul responsable de la manière dont sont présentés ici les différents concepts, et des libertés qui sont prises avec les ouvrages de référence. N'oubliez pas que vous devez croiser les informations de sources multiples afin de diminuer les risques d'erreurs.