Référence PHP 7.2
Référence PHP 7.1
PHP 7 est sorti le 3 décembre 2015. Il est livré avec un certain nombre de nouvelles fonctionnalités, de modifications et de problèmes de compatibilité descendante décrits ci-dessous.
Performance
Caractéristiques
Opérateur de comparaison combinée
Opérateur de fusion nul
Déclarations de type scalaire
Déclarations de type de retour
Cours anonymes
Syntaxe d'échappement Unicode Codepoint
Méthode call()
unserialize()
Classe IntlChar
Attentes
Déclarations use
en groupe
Expressions de retour du générateur
Délégation du générateur
Division entière avec intdiv()
Options session_start()
Fonction preg_replace_callback_array()
Fonctions CSPRNG
Prise en charge des constantes de tableau dans define()
Ajouts de réflexion
Changements
Assouplir les restrictions sur les mots réservés
Syntaxe des variables uniformes
Exceptions dans le moteur
Interface jetable
Sémantique des entiers
Extension JSON remplacée par JSOND
Échec du ZPP en cas de débordement
Corrections du comportement de foreach()
Modifications du comportement de list()
Modifications apportées à la division par zéro sémantique
Correctifs des valeurs de retour du gestionnaire de session personnalisé
Dépréciation des constructeurs PHP 4-Style
Suppression de date.timezone Avertissement
Suppression des balises PHP alternatives
Suppression de plusieurs blocs par défaut dans les instructions Switch
Suppression de la redéfinition des paramètres avec des noms en double
Suppression des API de serveur mort
Suppression du support hexadécimal dans les chaînes numériques
Suppression des fonctionnalités obsolètes
Reclassification et suppression des avis E_STRICT
Dépréciation de l'option Salt pour password_hash()
Erreur sur les littéraux octaux invalides
substr()
Changement de valeur de retour
FAQ
Qu'est-il arrivé à PHP 6 ?
L’aspect le plus important de PHP 7 réside sans aucun doute dans les incroyables améliorations de performances qu’il offre aux applications. Ceci est le résultat de la refactorisation du Zend Engine pour utiliser des structures de données plus compactes et moins d'allocations/désallocations de tas.
Les gains de performances sur les applications du monde réel varient, bien que de nombreuses applications semblent bénéficier d'une amélioration des performances d'environ 100 % - avec également une consommation de mémoire inférieure !
La base de code refactorisée offre également d'autres opportunités pour des optimisations futures (telles que la compilation JIT). Il semble donc que les futures versions de PHP continueront également à bénéficier d’améliorations en termes de performances.
Comparaisons des graphiques de performances PHP 7 :
Turbocharger le Web avec PHP 7
Points de référence du Sydney Talk de Rasmus
L'opérateur de comparaison combiné (ou opérateur de vaisseau spatial) est une notation abrégée permettant d'effectuer des comparaisons à trois voies à partir de deux opérandes. Il a une valeur de retour entière qui peut être :
un entier positif (si l'opérande de gauche est supérieur à l'opérande de droite)
0 (si les deux opérandes sont égaux)
un entier négatif (si l'opérande de droite est supérieur à l'opérande de gauche)
L'opérateur a la même priorité que les opérateurs d'égalité ( ==
, !=
, ===
, !==
) et a exactement le même comportement que les autres opérateurs de comparaison lâche ( <
, >=
, etc.). Il est également non associatif comme eux, donc le chaînage des opérandes (comme 1 <=> 2 <=> 3
) n'est pas autorisé.
// compare les chaînes lexicalementvar_dump('PHP' <=> 'Node'); // int(1)// compare les nombres par sizevar_dump(123 <=> 456); // int(-1)// compare les éléments du tableau correspondants avec un autrevar_dump(['a', 'b'] <=> ['a', 'b']); //int(0)
Les objets ne sont pas comparables, et donc les utiliser comme opérandes avec cet opérateur entraînera un comportement indéfini.
RFC : opérateur de comparaison combinée
L'opérateur de fusion nul (ou opérateur ternaire isset) est une notation abrégée permettant d'effectuer des vérifications isset()
dans l'opérateur ternaire. C'est une chose courante dans les applications, c'est pourquoi une nouvelle syntaxe a été introduite dans ce but précis.
// Code pré-PHP 7$route = isset($_GET['route']) ? $_GET['route'] : 'index';// Code PHP 7+$route = $_GET['route'] ?? 'indice';
RFC : opérateur de fusion nul
Les déclarations de type scalaire se déclinent en deux versions : coercitive (par défaut) et stricte . Les types de paramètres suivants peuvent désormais être appliqués (de manière coercitive ou stricte) : chaînes ( string
), entiers ( int
), nombres à virgule flottante ( float
) et booléens ( bool
). Ils augmentent les autres types introduits dans les versions PHP 5.x : noms de classes, interfaces, array
et callable
.
// Fonction de mode coercitif sumOfInts(int ...$ints) { return array_sum($ints); }var_dump(sumOfInts(2, '3', 4.1)); //int(9)
Pour activer le mode strict, une seule directive declare()
doit être placée en haut du fichier. Cela signifie que la rigueur de typage des scalaires est configurée fichier par fichier. Cette directive affecte non seulement les déclarations de type des paramètres, mais également le type de retour d'une fonction (voir Déclarations de type de retour), les fonctions PHP intégrées et les fonctions des extensions chargées.
Si la vérification de type échoue, une exception TypeError
(voir Exceptions dans le moteur) est levée. La seule clémence présente dans le typage strict est la conversion automatique des entiers en flottants (mais pas l'inverse) lorsqu'un entier est fourni dans un contexte flottant.
déclarer(strict_types=1);fonction multiplier(float $x, float $y) { retourner $x * $y; }fonction ajouter(int $x, int $y) { retourner $x + $y ; }var_dump(multiplier(2, 3.5)); // float(7)var_dump(add('2', 3)); // Erreur fatale : Uncaught TypeError : L'argument 1 passé à add() doit être du type entier, chaîne donnée...
Notez que seul le contexte d'invocation s'applique lorsque la vérification de type est effectuée. Cela signifie que le typage strict s'applique uniquement aux appels de fonction/méthode, et non aux définitions de fonction/méthode. Dans l'exemple ci-dessus, les deux fonctions auraient pu être déclarées dans un fichier strict ou coercitif, mais tant qu'elles sont appelées dans un fichier strict, les règles de typage strictes s'appliqueront.
Pauses en Colombie-Britannique
Les classes portant les noms int
, string
, float
et bool
sont désormais interdites.
RFC : déclarations de type scalaire
Les déclarations de type de retour permettent de spécifier le type de retour d'une fonction, d'une méthode ou d'une fermeture. Les types de retour suivants sont pris en charge : string
, int
, float
, bool
, array
, callable
, self
(méthodes uniquement), parent
(méthodes uniquement), Closure
, le nom d'une classe et le nom d'une interface.
function arraysSum(array ...$arrays): array{ return array_map(function(array $array): int { return array_sum($array); }, $tableaux); }print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));/* OutputArray( [0] => 6 [1] => 15 [2] => 24)*/
En ce qui concerne le sous-typage, l'invariance a été choisie pour les types de retour. Cela signifie simplement que lorsqu'une méthode est soit remplacée dans une classe sous-typée, soit implémentée comme défini dans un contrat, son type de retour doit correspondre exactement à la méthode qu'elle (ré)implémente.
classe A {}classe B étend A {}classe C { test de fonction publique() : A { renvoie le nouveau A ; } }la classe D étend C { // méthode de remplacement C::test() : A fonction publique test() : B // Erreur fatale due à une inadéquation de variance { renvoie le nouveau B ; } }
La méthode de substitution D::test() : B
provoque un E_COMPILE_ERROR
car la covariance n'est pas autorisée. Pour que cela fonctionne, la méthode D::test()
doit avoir un type de retour A
.
classe A {}interface UneInterface { test de fonction publique() : A; }classe B implémente SomeInterface { public function test() : A // tout va bien ! { renvoie null ; // Erreur fatale : Uncaught TypeError : la valeur de retour de B::test() doit être une instance de A, null renvoyé... } }
Cette fois, la méthode implémentée provoque la levée d'une exception TypeError
(voir Exceptions dans le moteur) lors de son exécution. En effet, null
n'est pas un type de retour valide : seule une instance de la classe A
peut être renvoyée.
RFC : Déclarations de type de retour
Les classes anonymes sont utiles lorsque des objets simples et ponctuels doivent être créés.
// Enregistreur de classe de code pré PHP 7 { journal des fonctions publiques ($ msg) { écho $msg; } }$util->setLogger(new Logger());// PHP 7+ code$util->setLogger(new class { public function log($msg) { écho $msg; } });
Ils peuvent transmettre des arguments à leurs constructeurs, étendre d’autres classes, implémenter des interfaces et utiliser des traits comme le ferait une classe normale :
class SomeClass {}interface SomeInterface {}trait SomeTrait {}var_dump(new class(10) extends SomeClass implémente SomeInterface { private $num; public function __construct($num) { $this->num = $num; } utilisez SomeTrait ; });/** Sortie:object(class@anonymous)#1 (1) { ["Code de ligne de commande0x104c5b612":"class@anonymous":private]=> int(10)}*/
L'imbrication d'une classe anonyme dans une autre classe ne lui donne accès à aucune méthode ou propriété privée ou protégée de cette classe externe. Afin d'utiliser les propriétés ou méthodes protégées de la classe externe, la classe anonyme peut étendre la classe externe. Pour utiliser les propriétés privées ou protégées de la classe externe dans la classe anonyme, il faut les passer via son constructeur :
<?phpclass Externe {privé $prop = 1; protégé $prop2 = 2 ; fonction protégée func1() {retourne 3 ; } fonction publique func2() { return new class($this->prop) extends Outer { private $prop3; fonction publique __construct($prop) { $this->prop3 = $prop; } fonction publique func3() { return $this->prop2 + $this->prop3 + $this->func1(); } } ; } }echo (nouveau externe) -> func2 () -> func3 (); // 6
RFC : classes anonymes
Cela permet à un point de code Unicode codé en UTF-8 d'être généré soit dans une chaîne entre guillemets doubles, soit dans un hérédoc. Tout point de code valide est accepté, les 0
en tête étant facultatifs.
echo "u{aa}"; // ªecho "u{0000aa}" ; // ª (comme avant mais avec des 0 facultatifs en tête)echo "u{9999}"; // ?
RFC : Syntaxe d'échappement de point de code Unicode
La nouvelle méthode call()
pour les fermetures est utilisée comme moyen abrégé d'invoquer une fermeture tout en y liant une portée d'objet. Cela crée un code plus performant et plus compact en supprimant le besoin de créer une fermeture intermédiaire avant de l'invoquer.
class A {private $x = 1;}// Code pré PHP 7$getXCB = function() {return $this->x;};$getX = $getXCB->bindTo(new A, 'A'); // écho de fermeture intermédiaire $getX(); // 1// PHP 7+ code$getX = function() {return $this->x;};echo $getX->call(new A); // 1
RFC : Fermeture : appel
unserialize()
Cette fonctionnalité vise à offrir une meilleure sécurité lors de la désérialisation d'objets sur des données non fiables. Il empêche d'éventuelles injections de code en permettant au développeur de mettre sur liste blanche les classes qui peuvent être non sérialisées.
// convertit tous les objets en objet __PHP_Incomplete_Class$data = unserialize($foo, ["allowed_classes" => false]);// convertit tous les objets en objet __PHP_Incomplete_Class sauf ceux de MyClass et MyClass2$data = unserialize($foo, [" Allowed_classes" => ["MyClass", "MyClass2"]]);// comportement par défaut (équivalent à l'omission du deuxième argument) qui accepte toutes les classes$data = unserialize($foo, ["allowed_classes" => true]);
RFC : désérialisation filtrée()
IntlChar
La nouvelle classe IntlChar
cherche à exposer des fonctionnalités ICU supplémentaires. La classe elle-même définit un certain nombre de méthodes et de constantes statiques pouvant être utilisées pour manipuler les caractères Unicode.
printf('%x', IntlChar::CODEPOINT_MAX); // 10ffffecho IntlChar::charName('@'); // COMMERCIAL ATvar_dump(IntlChar::ispunct('!')); // bool (vrai)
Pour utiliser cette classe, l'extension Intl
doit être installée.
Pauses en Colombie-Britannique
Les classes de l'espace de noms global ne doivent pas être appelées IntlChar
.
RFC : classe IntlChar
Les attentes sont une amélioration rétrocompatible de l’ancienne fonction assert()
. Ils permettent des assertions sans coût dans le code de production et offrent la possibilité de lancer des exceptions personnalisées en cas d'erreur.
Le prototype de la fonction assert()
est le suivant :
void assert (mixed $expression [, mixed $message]);
Comme avec l'ancienne API, si $expression
est une chaîne, alors elle sera évaluée. Si le premier argument est faux, alors l’assertion échoue. Le deuxième argument peut être soit une chaîne simple (provoquant le déclenchement d'une AssertionError), soit un objet d'exception personnalisé contenant un message d'erreur.
ini_set('assert.exception', 1);class CustomError extends AssertionError {}assert(false, new CustomError('Un message d'erreur'));
Cette fonctionnalité est accompagnée de deux paramètres PHP.ini (avec leurs valeurs par défaut) :
zend.assertions = 1
assert.exception = 0
zend.assertions a trois valeurs :
1 = générer et exécuter du code (mode développement)
0 = générer du code et y accéder au moment de l'exécution
-1 = ne génère aucun code (coût nul, mode production)
assert.exception signifie qu'une exception est levée lorsqu'une assertion échoue. Ceci est désactivé par défaut pour rester compatible avec l'ancienne fonction assert()
.
RFC : attentes
use
en groupe Cela donne la possibilité de regrouper plusieurs déclarations use
en fonction de l'espace de noms parent. Cela vise à supprimer la verbosité du code lors de l'importation de plusieurs classes, fonctions ou constantes relevant du même espace de noms.
// Pré PHP 7 coder somenamespaceClassA;utiliser somenamespaceClassB;utiliser somenamespaceClassC comme C;utiliser la fonction somenamespacefn_a;utiliser la fonction somenamespacefn_b;utiliser la fonction somenamespace fn_c;utiliser const somenamespaceConstA;utiliser const somenamespaceConstB;utiliser const somenamespaceConstC;// PHP 7+ codeuse somenamespace{ClassA, ClassB, ClassC as C};utiliser la fonction somenamespace{fn_a, fn_b, fn_c};utiliser const somenamespace{ConstA, ConstB, ConstC};
RFC : Déclarations d'utilisation de groupe
Cette fonctionnalité s'appuie sur la fonctionnalité de générateur introduite dans PHP 5.5. Il permet d'utiliser une instruction return
dans un générateur pour permettre le retour d'une expression finale (le retour par référence n'est pas autorisé). Cette valeur peut être récupérée à l'aide de la nouvelle méthode Generator::getReturn()
, qui ne peut être utilisée qu'une fois que le générateur a fini de produire des valeurs.
// La syntaxe IIFE est désormais possible - voir la sous-section Uniform Variable Syntax dans la section Modifications$gen = (function() { rendement 1; rendement 2; retour 3; })();foreach ($gen as $val) { echo $val, PHP_EOL; }echo $gen->getReturn(), PHP_EOL;// sortie:// 1// 2// 3
Être capable de renvoyer explicitement une valeur finale à partir d'un générateur est une capacité pratique à avoir. En effet, cela permet à un générateur de renvoyer une valeur finale (provenant peut-être d'une forme de calcul de coroutine) qui peut être spécifiquement gérée par le code client exécutant le générateur. C'est beaucoup plus simple que de forcer le code client à vérifier d'abord si la valeur finale a été renvoyée, puis, si c'est le cas, à gérer cette valeur spécifiquement.
RFC : expressions de retour du générateur
La délégation des générateurs s'appuie sur la capacité de renvoyer des expressions à partir des générateurs. Pour ce faire, il utilise une nouvelle syntaxe de yield from <expr>
, où peut être n'importe quel objet ou tableau Traversable
. Ceci sera avancé jusqu'à ce qu'il ne soit plus valide, puis l'exécution se poursuivra dans le générateur appelant. Cette fonctionnalité permet de décomposer les instructions yield
en opérations plus petites, favorisant ainsi un code plus propre et plus réutilisable.
fonction gén() { rendement 1 ; rendement 2 ; renvoie le rendement de gen2(); }fonction gen2() { rendement 3 ; retourner 4 ; }$gen = gen();foreach ($gen comme $val) { echo $val, PHP_EOL; }echo $gen->getReturn();// sortie// 1// 2// 3// 4
RFC : Délégation du générateur
intdiv()
La fonction intdiv()
a été introduite pour gérer la division où un entier doit être renvoyé.
var_dump(intdiv(10, 3)); //int(3)
Pauses en Colombie-Britannique
Les fonctions de l'espace de noms global ne doivent pas être appelées intdiv
.
RFC : intdiv()
session_start()
Cette fonctionnalité donne la possibilité de transmettre un tableau d'options à la fonction session_start()
. Ceci est utilisé pour définir les options php.ini basées sur la session :
session_start(['cache_limiter' => 'privé']); // définit l'option session.cache_limiter sur privé
Cette fonctionnalité introduit également un nouveau paramètre php.ini ( session.lazy_write
) qui est, par défaut, défini sur true et signifie que les données de session ne sont réécrites que si elles changent.
RFC : introduction des options session_start()
preg_replace_callback_array()
Cette nouvelle fonction permet d'écrire le code plus proprement lors de l'utilisation de la fonction preg_replace_callback()
. Avant PHP 7, les rappels qui devaient être exécutés par expression régulière nécessitaient que la fonction de rappel (deuxième paramètre de preg_replace_callback()
) soit polluée par de nombreux branchements (une méthode hacky au mieux).
Désormais, les rappels peuvent être enregistrés pour chaque expression régulière à l'aide d'un tableau associatif, où la clé est une expression régulière et la valeur est un rappel.
Signature de fonction :
string preg_replace_callback_array(array $regexesAndCallbacks, string $input);
$tokenStream = []; // [tokenName, lexème] pairs$input = <<<'end'$a = 3; // fin d'initialisation de la variable;// pré PHP 7 codepreg_replace_callback( [ '~$[a-z_][azd_]*~i', '~=~', '~[d]+~', '~;~', '~//.*~' ], fonction ($match) utiliser (&$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' => fonction ($match) utiliser (&$tokenStream) { $tokenStream[] = ['T_VARIABLE', $match[0]]; }, '~=~' => fonction ($match) utiliser ($tokenStream) { $tokenStream[] = ['T_ASSIGN', $match[0]]; }, '~[d]+~' => fonction ($match) utiliser ($tokenStream) { $tokenStream[] = ['T_NUM', $match[0]]; }, '~;~' => fonction ($match) utiliser ($tokenStream) { $tokenStream[] = ['T_TERMINATE_STMT', $match[0]]; }, '~//.*~' => fonction ($match) utiliser ($tokenStream) { $tokenStream[] = ['T_COMMENT', $match[0]]; } ], $entrée);
Pauses en Colombie-Britannique
Les fonctions de l'espace de noms global ne doivent pas être appelées preg_replace_callback_array
.
RFC : ajouter la fonction preg_replace_callback_array
Cette fonctionnalité introduit deux nouvelles fonctions pour générer des entiers et des chaînes cryptographiquement sécurisés. Ils exposent des API simples et sont indépendants de la plate-forme.
Signatures de fonction :
string random_bytes(int length); int random_int(int min, int max);
Les deux fonctions émettront une exception Error
si une source suffisamment aléatoire ne peut pas être trouvée.
Pauses en Colombie-Britannique
Les fonctions de l'espace de noms global ne doivent pas être appelées random_int
ou random_bytes
.
RFC : CSPRNG facile à utiliser pour les utilisateurs
define()
La possibilité de définir des constantes de tableau a été introduite dans PHP 5.6 à l'aide du mot-clé const
. Cette capacité a désormais également été appliquée à la fonction define()
:
définir('ALLOWED_IMAGE_EXTENSIONS', ['jpg', 'jpeg', 'gif', 'png']);
RFC : aucune RFC disponible
Deux nouvelles classes de réflexion ont été introduites dans PHP 7. La première est ReflectionGenerator
, qui est utilisée pour l'introspection sur les générateurs :
classe ReflectionGenerator { public __construct(Generator $gen) tableau public getTrace($options = DEBUG_BACKTRACE_PROVIDE_OBJECT) public int getExecutingLine (void) chaîne publique getExecutingFile (void) public ReflectionFunctionAbstract getFunction (void) Objet public getThis (void) Générateur public getExecutingGenerator (void) }
Le second est ReflectionType
pour mieux prendre en charge les fonctionnalités de déclaration de type scalaire et de retour :
classe Type de réflexion { public bool makesNull(void) public bool isBuiltin(void) public string __toString(void) }
De plus, deux nouvelles méthodes ont été introduites dans ReflectionParameter
:
classe ReflectionParameter { // ... public bool hasType(void) public ReflectionType getType(void) }
Ainsi que deux nouvelles méthodes dans ReflectionFunctionAbstract
:
classe RéflexionFonctionRésumé { // ... public bool hasReturnType(void) public ReflectionType getReturnType(void) }
Pauses en Colombie-Britannique
Les classes de l'espace de noms global ne doivent pas être appelées ReflectionGenerator
ou ReflectionType
.
RFC : aucune RFC disponible
Les mots réservés globalement en tant que noms de propriétés, de constantes et de méthodes dans les classes, les interfaces et les traits sont désormais autorisés. Cela réduit la surface des ruptures BC lorsque de nouveaux mots-clés sont introduits et évite les restrictions de nom sur les API.
Ceci est particulièrement utile lors de la création de DSL internes avec des interfaces fluides :
// 'new', 'private' et 'for' étaient auparavant inutilisablesProject::new('Project Name')->private()->for('Purpose here')->with('username here');
La seule limitation est que le mot-clé class
ne peut toujours pas être utilisé comme nom de constante, sinon il entrerait en conflit avec la syntaxe de résolution du nom de classe ( ClassName::class
).
RFC : Lexer contextuel
Ce changement apporte une bien plus grande orthogonalité aux opérateurs de variables en PHP. Il permet un certain nombre de nouvelles combinaisons d'opérateurs qui étaient auparavant interdites, et introduit ainsi de nouvelles façons de réaliser d'anciennes opérations dans un code plus concis.
// nesting ::$foo::$bar::$baz // accède à la propriété $baz de la propriété $foo::$bar// nesting ()foo()() // invoque le retour de foo() // Opérateurs sur les expressions entourées de ()(function () {})() // Syntaxe IIFE de JS
La possibilité de combiner arbitrairement des opérateurs de variables est venue de l'inversion de la sémantique d'évaluation des références de variables indirectes, de propriétés et de méthodes. Le nouveau comportement est plus intuitif et suit toujours un ordre d'évaluation de gauche à droite :
// ancien sens // nouveau sens$$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']()
Pauses en Colombie-Britannique
Le code qui reposait sur l'ancien ordre d'évaluation doit être réécrit pour utiliser explicitement cet ordre d'évaluation avec des accolades (voir la colonne du milieu ci-dessus). Cela rendra le code à la fois compatible avec PHP 7.x et rétrocompatible avec PHP 5.x.
RFC : syntaxe de variable uniforme
Les exceptions dans le moteur convertissent de nombreuses erreurs fatales et récupérables en exceptions. Cela permet une dégradation progressive des applications grâce à des procédures personnalisées de gestion des erreurs. Cela signifie également que les fonctionnalités basées sur le nettoyage telles que la clause finally
et les destructeurs d'objets seront désormais exécutées. De plus, en utilisant des exceptions pour les erreurs d'application, des traces de pile seront produites pour des informations de débogage supplémentaires.
function sum(float ...$numbers) : float{ return array_sum($numbers); }essayez { $total = somme(3, 4, null); } catch (TypeError $typeErr) { // gère l'erreur de type ici}
La nouvelle hiérarchie des exceptions est la suivante :
interface Throwable |- Exception implements Throwable |- ... |- Error implements Throwable |- TypeError extends Error |- ParseError extends Error |- AssertionError extends Error |- ArithmeticError extends Error |- DivisionByZeroError extends ArithmeticError
Consultez la sous-section Throwable Interface dans la section Modifications pour plus d’informations sur cette nouvelle hiérarchie d’exceptions.
Pauses en Colombie-Britannique
Les gestionnaires d'erreurs personnalisés utilisés pour gérer (et généralement ignorer) les erreurs fatales récupérables ne fonctionneront plus puisque des exceptions seront désormais levées.
Les erreurs d'analyse se produisant dans le code eval()
deviendront désormais des exceptions, nécessitant qu'elles soient encapsulées dans un bloc try...catch
RFC : exceptions dans le moteur
Ce changement affecte la hiérarchie des exceptions de PHP en raison de l'introduction d'exceptions dans le moteur. Plutôt que de placer les erreurs fatales et récupérables sous la hiérarchie de classes Exception
préexistante, il a été décidé d'implémenter une nouvelle hiérarchie d'exceptions pour empêcher le code PHP 5.x d'attraper ces nouvelles exceptions avec catch-all ( catch (Exception $e)
) clauses.
La nouvelle hiérarchie des exceptions est la suivante :
interface Throwable |- Exception implements Throwable |- ... |- Error implements Throwable |- TypeError extends Error |- ParseError extends Error |- AssertionError extends Error |- ArithmeticError extends Error |- DivisionByZeroError extends ArithmeticError
L'interface Throwable
est implémentée par les hiérarchies de classes de base Exception
et Error
et définit le contrat suivant :
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
ne peut pas être implémenté par des classes définies par l'utilisateur. Au lieu de cela, une classe d'exceptions personnalisée doit étendre l'une des classes d'exceptions préexistantes en PHP.
RFC : interface jetable
La sémantique de certains comportements basés sur des entiers a changé dans le but de les rendre plus intuitifs et indépendants de la plate-forme. Voici une liste de ces changements :
La conversion de NAN
et INF
en un entier donnera toujours 0
Le décalage au niveau du bit d'un nombre négatif de bits est désormais interdit (provoque un retour booléen (faux) et émet un E_WARNING)
Les décalages de bits vers la gauche d'un certain nombre de bits au-delà de la largeur de bits d'un entier donneront toujours 0.
Les décalages de bits vers la droite d'un nombre de bits au-delà de la largeur de bits d'un entier donneront toujours 0 ou -1 (en fonction du signe)
Pauses en Colombie-Britannique
Toute dépendance à l'ancienne sémantique pour ce qui précède ne fonctionnera plus
RFC : sémantique des entiers
La licence de l'ancienne extension JSON était considérée comme non libre, ce qui causait des problèmes pour de nombreuses distributions basées sur Linux. L'extension a depuis été remplacée par JSOND et s'accompagne de gains de performances et de ruptures de compatibilité ascendante.
Pauses en Colombie-Britannique
Un nombre ne doit pas se terminer par un point décimal (c'est-à-dire que 34.
doit être remplacé par 34.0
ou simplement 34
)
L'exposant e
ne doit pas suivre immédiatement le point décimal (c'est-à-dire que 3.e3
doit être remplacé par 3.0e3
ou simplement 3e3
)
RFC : remplacer l'extension json actuelle par jsond
La coercition entre les flottants et les entiers peut se produire lorsqu'un flottant est transmis à une fonction interne attendant un entier. Si le flottant est trop grand pour être représenté sous forme d'entier, la valeur sera tronquée silencieusement (ce qui peut entraîner une perte de magnitude et de signe). Cela peut introduire des bogues difficiles à trouver. Ce changement cherche donc à avertir le développeur lorsqu'une conversion implicite d'un flottant en un entier s'est produite et a échoué en renvoyant null
et en émettant un E_WARNING.
Pauses en Colombie-Britannique
Le code qui fonctionnait autrefois silencieusement émettra désormais un E_WARNING et peut échouer si le résultat de l'invocation de la fonction est directement transmis à une autre fonction (puisque null
sera désormais transmis).
RFC : échec de ZPP en cas de débordement
foreach()
La boucle foreach()
de PHP présentait un certain nombre de cas étranges. Tout cela était basé sur l'implémentation et provoquait de nombreux comportements indéfinis et incohérents lors de l'itération entre les copies et les références d'un tableau, lors de l'utilisation de manipulateurs d'itérateur comme current()
et reset()
, lors de la modification du tableau en cours d'itération, etc.
Ce changement élimine le comportement indéfini de ces cas extrêmes et rend la sémantique plus prévisible et intuitive.
foreach()
par valeur sur les tableaux
$array = [1,2,3];$array2 = &$array;foreach($array as $val) { unset ($ tableau [1]); // modifie le tableau en cours d'itération echo "{$val} - ", current ($ array), PHP_EOL; }// Résultat pré PHP 71 - 33 -// Résultat PHP 7+1 - 12 - 13 - 1
Lorsque la sémantique par valeur est utilisée, le tableau itéré n'est plus modifié sur place. current()
a également désormais un comportement défini, où il commencera toujours au début du tableau.
foreach()
par référence sur les tableaux et les objets et par valeur sur les objets
$array = [1,2,3];foreach($array as &$val) { echo "{$val} - ", actuel($array), PHP_EOL; }// Résultat1 pré-PHP 7 - 22 - 33 -// Résultat PHP 7+1 - 12 - 13 - 1
La fonction current()
n'est plus affectée par l'itération de foreach()
sur le tableau. De plus, foreach()
imbriqués utilisant la sémantique par référence fonctionnent désormais indépendamment les uns des autres :
$array = [1,2,3];foreach($array as &$val) { echo $val, PHP_EOL; foreach ($tableau comme &$val2) { unset ($ tableau [1]); écho $val, PHP_EOL; } }// Résultat pré-PHP 7111// Résultat PHP 7+111333
Pauses en Colombie-Britannique
Toute dépendance à l’ancienne sémantique (originale et non documentée) ne fonctionnera plus.
RFC : correction du comportement "foreach"
list()
La fonction list()
a été documentée comme ne prenant pas en charge les chaînes, cependant dans quelques cas, des chaînes auraient pu être utilisées :
// déréférencement de tableau$str[0] = 'ab';list($a, $b) = $str[0];echo $a; // écho $b; // b// déréférencement d'objet$obj = new StdClass();$obj->prop = 'ab';list($a, $b) = $obj->prop;echo $a; // écho $b; // b// fonction returnfunction func() {retourne 'ab'; }list($a, $b) = func();var_dump($a, $b);echo $a; // écho $b; //b
Cela a maintenant été modifié, rendant l'utilisation de chaînes avec list()
interdite dans tous les cas.
De plus, list()
vides sont désormais une erreur fatale, et l'ordre d'attribution des variables a été modifié de gauche à droite :
$a = [1, 2];list($a, $b) = $a;// ANCIEN : $a = 1, $b = 2// NOUVEAU : $a = 1, $b = null + "Non défini index 1"$b = [1, 2];list($a, $b) = $b;// ANCIEN : $a = null + "Indice non défini 0", $b = 2// NOUVEAU : $a = 1, $b = 2
Pauses en Colombie-Britannique
Rendre list()
égal à n’importe quelle valeur de chaîne non directe n’est plus possible. null
sera désormais la valeur des variables $a
et $b
dans les exemples ci-dessus
Invoquer list()
sans aucune variable provoquera une erreur fatale
Le recours à l'ancien ordre d'affectation de droite à gauche ne fonctionnera plus
RFC : correction de l'incohérence du comportement de list()
RFC : arbre de syntaxe abstraite
Avant PHP 7, lorsqu'un diviseur était égal à 0 pour les opérateurs diviser (/) ou module (%), un E_WARNING était émis et false
était renvoyé. Cela n'avait aucun sens pour qu'une opération arithmétique renvoie un booléen dans certains cas, et le comportement a donc été rectifié dans PHP 7.
Le nouveau comportement amène l'opérateur de division à renvoyer un flottant sous la forme +INF, -INF ou NAN. L'opérateur de module E_WARNING a été supprimé et (avec la nouvelle fonction intdiv()
) lèvera une exception DivisionByZeroError
. De plus, la fonction intdiv()
peut également générer une ArithmeticError
lorsque des arguments entiers valides sont fournis, ce qui provoque un résultat incorrect (en raison d'un dépassement d'entier).
var_dump(3/0); // float(INF) + E_WARNINGvar_dump(0/0); // float(NAN) + E_WARNINGvar_dump(0%0); // DivisionByZeroErrorintdiv(PHP_INT_MIN, -1); // Erreur Arithmétique
Pauses en Colombie-Britannique
L'opérateur de division ne renverra plus false
(qui aurait pu être contraint silencieusement à 0 dans une opération arithmétique)
L'opérateur de module lèvera désormais une exception avec un diviseur 0 au lieu de renvoyer false
RFC : aucune RFC disponible
Lors de l'implémentation de gestionnaires de session personnalisés, les fonctions de prédicat de SessionHandlerInterface
qui attendent une valeur de retour true
ou false
ne se sont pas comportées comme prévu. En raison d'une erreur dans l'implémentation précédente, seule une valeur de retour -1
était considérée comme fausse - ce qui signifie que même si le booléen false
était utilisé pour indiquer un échec, il était considéré comme un succès :
<?phpclass FileSessionHandler implémente SessionHandlerInterface {privé $savePath ; fonction ouverte ($ savePath, $ sessionName) {retourne faux ; // échoue toujours } function close(){return true;} function read($id){} function write($id, $data){} function destroy($id){} function gc($maxlifetime){} }session_set_save_handler(nouveau FileSessionHandler());session_start(); // ne provoque pas d'erreur dans le code pré-PHP 7
Désormais, ce qui précède échouera avec une erreur fatale. Avoir une valeur de retour -1
continuera également à échouer, tandis que 0
et true
continueront à signifier un succès. Toute autre valeur renvoyée provoquera désormais un échec et émettra un E_WARNING.
Pauses en Colombie-Britannique
Si un boolean false
est renvoyé, cela échouera maintenant
Si quelque chose d'autre qu'un booléen, 0
ou -1
est renvoyé, cela échouera et provoquera l'émission d'un avertissement.
RFC : correction de la gestion des valeurs de retour du gestionnaire de session personnalisé
Les constructeurs PHP 4 ont été conservés dans PHP 5 aux côtés du nouveau __construct()
. Désormais, les constructeurs de style PHP 4 sont obsolètes au profit d'une seule méthode ( __construct()
) à appeler lors de la création d'un objet. En effet, les conditions d'appel du constructeur de style PHP 4 ont entraîné une surcharge cognitive supplémentaire pour les développeurs, ce qui pourrait également être déroutant pour les inexpérimentés.
Par exemple, si la classe est définie dans un espace de noms ou si une méthode __construct()
existait, un constructeur de style PHP 4 a été reconnu comme une méthode simple. S'il était défini au-dessus d'une méthode __construct()
, alors un avis E_strict serait émis, mais toujours reconnu comme une méthode simple.
Maintenant, dans PHP 7, si la classe n'est pas dans un espace de noms et qu'il n'y a pas de méthode __construct()
présente, le constructeur de style PHP 4 sera utilisé comme constructeur mais un E_Deprecated sera émis. Dans PHP 8, le constructeur de style PHP 4 sera toujours reconnu comme une méthode simple et l'avis E_Deprecated disparaîtra.
Colombie-Britannique
Les gestionnaires d'erreurs personnalisés peuvent être affectés par l'élévation des avertissements E_Delecated. Pour résoudre ce problème, mettez simplement à jour le nom du constructeur de classe sur __construct
.
RFC: Retirez les constructeurs PHP 4
Lorsque des fonctions basées sur la date ou le temps ont été invoquées et que le fuseau horaire par défaut n'avait pas été défini, un avertissement a été émis. Le correctif consistait à définir le paramètre date.timezone
Ini sur un fuseau horaire valide, mais cela a forcé les utilisateurs à avoir un fichier php.ini et à le configurer au préalable. Étant donné que c'était le seul réglage qui avait un avertissement attaché, et il a fait défaut à l'UTC de toute façon, l'avertissement a maintenant été supprimé.
RFC: supprimer la date.
Les étiquettes PHP alternatives <%
(et <%=
), %>
, <script language="php">
, et </script>
ont maintenant été supprimées.
Colombie-Britannique
Le code qui reposait sur ces balises alternatives doit être mise à jour sur les balises d'ouverture et de clôture normales ou courtes. Cela peut être fait manuellement ou automatisé avec ce script de portage.
RFC: supprimer des balises PHP alternatives
Auparavant, il était possible de spécifier plusieurs instructions de bloc default
dans une instruction Switch (où le dernier bloc default
n'a été exécuté que). Cette capacité (inutile) a maintenant été supprimée et provoque une erreur fatale.
Colombie-Britannique
Tout code écrit (ou plus probablement généré) qui a créé des instructions de commutation avec plusieurs blocs default
deviendra désormais une erreur fatale.
RFC: faire de la définition de plusieurs cas par défaut dans un commutateur une erreur de syntaxe
Auparavant, il était possible de spécifier des paramètres avec des noms en double dans une définition de fonction. Cette capacité a maintenant été supprimée et provoque une erreur fatale.
fonction foo ($ version, $ version) {return $ version; } echo foo (5, 7); // pre php 7 result7 // php 7+ ResultFatal Erreur: redéfinition du paramètre $ version dans /redEfinition-of-Parameters.php
Colombie-Britannique
Les paramètres de fonction avec nom en double deviendront désormais une erreur fatale.
Les sapis suivants ont été supprimés du noyau (dont la plupart ont été déplacés vers PECL):
SAPI / AOLSERVER
sapi / apache
sapi / apache_hooks
sapi / apache2filter
sapi / caudium
sapi / continuité
SAPI / ISAPI
sapi / milter
sapi / nsapi
SAPI / PHTTPD
sapi / pi3web
sapi / roxen
SAPI / THTTPD
SAPI / TUX
sapi / webjames
ext / mssql
ext / mysql
ext / sybase_ct
ext / ereg
RFC: Retrait des sapis et extensions portés par PHP7 ou pas encore PHP7
Un numéro hexadécimal filandreux n'est plus reconnu comme numérique.
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
La raison de ce changement est de promouvoir une meilleure cohérence entre la gestion des numéros hexadécimaux filandreux à travers la langue. Par exemple, les moulages explicites ne reconnaissent pas les numéros hexadécimaux rigoureux:
var_dump ((int) '0x123'); // int (0)
Au lieu de cela, les nombres hexadécimaux filés doivent être validés et convertis à l'aide de la fonction filter_var()
:
var_dump (filter_var ('0x123', filter_validate_int, filter_flag_allow_hex)); // int (291)
Colombie-Britannique
Ce changement affecte la fonction is_numeric()
et divers opérateurs, y compris ==
, +
, -
, *
, /
, %
, **
, ++
et --
RFC: supprimer le support hexagonal dans les chaînes numériques
Toutes les fonctionnalités obsolètes ont été supprimées, notamment:
L'extension MySQL d'origine (EXT / MYSQL)
L'extension ereg (ext / ereg)
Attribution new
par référence
Les appels à portée de méthodes non statiques à partir d'un $this
incompatible $ (comme Foo::bar()
de l'extérieur d'une classe, où bar()
n'est pas une méthode statique)
Colombie-Britannique
Tout code fonctionnant avec des avertissements de dépréciation dans PHP 5 ne fonctionnera plus (vous avez été averti!)
RFC: supprimez les fonctionnalités obsolètes dans PHP 7
Les avis E_strict ont toujours été un peu une zone grise en leur sens. Cette modification supprime complètement cette catégorie d'erreur et supprime le préavis E_strict, le modifie en un E_Deprecated si la fonctionnalité sera supprimée à l'avenir, la modifie en un e_notice ou la promouvra en un e_warning.
Colombie-Britannique
Parce que E_strict est dans la catégorie d'erreur de gravité la plus basse, toute promotion d'erreur à un e_warning peut casser les gestionnaires d'erreurs personnalisés
RFC: reclasser les avis E_Strict
password_hash()
Avec l'introduction de la nouvelle API de hachage de mot de passe dans PHP 5.5, beaucoup ont commencé à l'implémenter et à générer leurs propres sels. Malheureusement, beaucoup de ces sels ont été générés à partir de fonctions cryptographiquement peu sûres comme mt_rand (), ce qui rend le sel beaucoup plus faible que ce qui aurait été généré par défaut. (Oui, un sel est toujours utilisé lorsque le hachage des mots de passe avec cette nouvelle API!) L'option pour générer des sels a donc été obsolète pour empêcher les développeurs de créer des sels en sécurité.
RFC: pas de RFC disponible
Les littéraux octaux non valides provoqueront désormais une erreur d'analyse plutôt que d'être tronqué et ignoré silencieusement.
Echo 0678; // Erreur d'analyse: littéral numérique non valide dans ...
Colombie-Britannique
Tous les littéraux octaux non valides en code provoqueront désormais des erreurs d'analyse
RFC: pas de RFC disponible
substr()
retour de valeur de retour substr()
renvoie désormais une chaîne vide au lieu de false
lorsque la position de début de la troncature est égale à la longueur de la chaîne:
var_dump (substr ('a', 1)); // pre php 7 resultbool (false) // php 7+ resultstring (0) ""
substr()
peut toujours renvoyer false
dans d'autres cas, cependant.
Colombie-Britannique
Le code qui a strictement vérifié une valeur de retour bool(false)
peut désormais être sémantiquement invalide
RFC: pas de RFC disponible
PHP 6 était la principale version PHP qui n'a jamais été révélée. Il était censé présenter un soutien complet à Unicode dans le cœur, mais cet effort était trop ambitieux avec trop de complications survenant. Les raisons prédominantes pour lesquelles la version 6 a été ignorée pour cette nouvelle version majeure est la suivante:
Pour éviter la confusion . De nombreuses ressources ont été écrites sur PHP 6 et une grande partie de la communauté savait ce qui y avait présenté. PHP 7 est une bête complètement différente avec des objectifs entièrement différents (spécifiquement sur les performances) et des ensembles de fonctionnalités entièrement différents. Ainsi, une version a été ignorée pour éviter toute confusion ou idées fausses entourant ce qu'est PHP 7.
Pour laisser mentir les chiens endormis . Le PHP 6 a été considéré comme un échec et une grande quantité de code PHP 6 reste toujours dans le référentiel PHP. Il a donc été considéré comme le mieux pour dépasser la version 6 et recommencer dans la prochaine version principale, version
RFC: Nom de la prochaine version de PHP