L'heure de sortie de PHP8.2 n'a pas encore été déterminée, mais sa sortie est prévue fin 2022. Cet article vous présentera les fonctionnalités, les améliorations de performances, les fonctionnalités obsolètes, etc. dans la nouvelle version.
Recommandations associées : Les dernières avancées de PHP8.2, les nouvelles fonctionnalités seront bientôt gelées !
null et false seront traités comme des types indépendants
PHP ne tombera pas dans la direction parfaite de la sécurité des types, mais d'un point de vue technique, il vaut la peine de traiter null et false comme des types de données indépendants . Dans des circonstances normales, de nombreuses fonctions courantes en PHP indiqueront une erreur en renvoyant false. Par exemple, dans file_get_content :
file_get_contents(/* … */): string|false
Dans le passé, false pouvait être utilisé dans les types union, mais il ne pouvait pas être utilisé indépendamment. En PHP8.2, il peut être utilisé seul :
function alwaysFalse(): false { return false; }
Bien sûr, certains développeurs. sont prudents quant à cette approche. Il ne prend pas en charge true en tant que type indépendant. Ces développeurs pensent que false n'est qu'une valeur et que les types doivent représenter des catégories plutôt que des valeurs. Bien entendu, dans le système de types, il existe une notion de type d’unité, qui est un type qui n’autorise qu’une seule valeur. Mais est-ce que ça marche vraiment ?
Mais une autre RFC discute également de l'ajout de true en tant que type à PHP.
Un null séparé a beaucoup de sens, vous pouvez donc simplement implémenter le modèle d'objet nul :
class Post { public function getAuthor(): ?string { /* … */ } } class NullPost extends Post { public function getAuthor(): null { /* … */ } }
Cela permet à NullPost::getAuthor() de dire qu'il ne retournera que null, sans avoir à combiner null et une chaîne comme avant la déclaration.
Propriétés dynamiques obsolètes
Il s'agit d'une meilleure conception pour la spécification du langage, mais cela limite également de nombreuses utilisations. Les propriétés dynamiques sont obsolètes dans PHP 8.2 et généreront des exceptions d'erreur dans PHP.
Que sont les propriétés dynamiques ? Autrement dit, vous ne déclarez pas ces propriétés dans la classe, mais vous pouvez toujours les définir et les obtenir :
class Post { public string $title; } // … $post->name = 'Name'; // 在PHP8.2中不能这样使用,因为并没有在类中声明
Mais ne vous inquiétez pas, les méthodes magiques telles que __set et __get fonctionneront toujours comme prévu :
class Post { private array $properties = []; public function __set(string $name, mixed $value): void { $this->properties[$name] = $value; } } // … $post->name = 'Name';
La même chose est vrai pour les objets standard : stdClass continuera à prendre en charge la propriété dynamique.
PHP était autrefois un langage dynamique très dynamique, mais maintenant de nombreuses personnes sont prêtes à accepter des méthodes de programmation plus rigoureuses. Être aussi strict que possible et s'appuyer autant que possible sur l'analyse statique est une bonne chose, car cela permet aux développeurs d'écrire un meilleur code.
Cependant, certains développeurs qui apprécient les propriétés dynamiques peuvent être très insatisfaits de ce changement. Si vous ne souhaitez pas voir ces avertissements lorsque vous utilisez PHP8.2, vous pouvez faire ceci :
Vous pouvez utiliser #[AllowDynamicProperties]
#[AllowDynamicProperties] class Post { public string $title; } // … $post->name = 'Name'; // 一切正常
Un autre. La méthode consiste à modifier le niveau d’alarme, mais cela n’est pas recommandé. Vous rencontrerez des problèmes lorsque vous envisagez de passer à PHP9.0.
error_reporting(E_ALL ^ E_DEPRECATED);
Désensibilisation des paramètres lors du suivi des appels
Qu'est-ce que la désensibilisation des paramètres ? Lors du développement, lorsque nous rencontrons des erreurs, nous utiliserons Trace pour déboguer, mais la pile actuelle enregistre certaines données sensibles, telles que les variables d'environnement, les mots de passe et les utilisateurs.
En PHP8.2, certaines modifications de paramètres sont autorisées (Caviarder, appelons-le édition, a une certaine signification de modification, mais il n'est pas approprié de l'appeler directement modification), comme la désensibilisation de certains paramètres afin que les valeurs appelantes de ces paramètres Il ne sera pas répertorié dans les informations de la pile :
function test( $foo, #[\SensitiveParameter] $bar, $baz ) { throw new Exception('Error'); } test('foo', 'bar', 'baz');
Si une erreur est signalée, vous constaterez que la deuxième barre de paramètres n'enregistre pas la valeur réelle. Cela peut avoir un effet désensibilisant. Si le mot de passe est transmis, il ne sera pas enregistré.
Fatal error: Uncaught Exception: Error in test.php:8 Stack trace: #0 test.php(11): test('foo', Object(SensitiveParameterValue), 'baz') #1 {main} thrown in test.php on line 8
Certaines méthodes d'appel d'objets sont obsolètes
Certaines méthodes précédentes d'appel d'objets sont obsolètes. Certains d'entre eux doivent être appelés via call_user_func($callable), plutôt que d'être appelés directement par $callable().
"self::method" "parent::method" "static::method" ["self", "method"] ["parent", "method"] ["static", "method"] ["Foo", "Bar::method"] [new Foo, "Bar::method"]
Pourquoi fais-tu ça ? Nikita l'a bien expliqué dans la discussion RFC :
Ces appels obsolètes sont spécifiques au contexte, et la méthode référencée par "self::method" dépend de la classe à partir de laquelle l'appel ou la vérification de l'appelabilité est effectué. En fait, cela s'applique généralement également aux deux derniers cas lorsqu'il est utilisé sous la forme [new Foo, "parent::method"].
Réduire la dépendance au contexte des objets appelables est un objectif secondaire de cette RFC. Après cette RFC, la seule dépendance de portée restante est la visibilité de la méthode : "Foo::bar" peut être visible dans une portée mais pas dans une autre. Si à l’avenir les objets appelables sont limités aux méthodes publiques, alors les types appelables deviendront bien définis et pourront être utilisés comme types de propriétés. Cependant, les modifications apportées à la gestion de la visibilité ne sont pas recommandées dans le cadre de cette RFC.
Améliorer le mécanisme de détection et le niveau des variables non définies
Les variables non définies sont celles qui n'ont pas été initialisées avant d'être lues. L'accès à une variable non définie émet actuellement E_WARNING "Avertissement : variable non définie $varname" et traite la variable comme nulle, mais n'interrompt pas l'exécution, permettant à l'exécution du code de continuer sans relâche, mais éventuellement dans un état inattendu.
Actuellement, vous pouvez utiliser certaines configurations pour que PHP génère des exceptions de niveau d'erreur pour les variables non définies lors de l'exécution, mais cela nécessite une configuration distincte. PHP devrait fournir des contrôles plus sûrs par défaut.
一般什么情况下会出现未定义变量的情况呢?
用法1
变量在某个分支中声明,比如在if中设置一个值。
if ( $user -> admin ) { $restricted = false ; } if ( $restricted ) { die ( '你没有进入这里的权限' ) ; }
用法2
变量拼写错误:
$name = 'Joe'; echo 'Welcome, ' . $naame;
这种用法在1中也可能会发生:
if ($user->admin) { $restricted = false; } else { $restrictedd = true; } if ($restricted) { die('You do not have permission to be here'); }
用法3
在循环中定义,但这个循环可能并没有执行:
while ($item = $itr->next()) { $counter++; // 定义变量 } // 这里调用了变量,但是很有可能并没有定义这个变量 echo 'You scanned ' . $counter . ' items';
解决方法
在这些分支之前提前定义好一个默认值。
对于第1种用法:
$restricted = true; if ($user->admin) { $restricted = false; } if ($restricted) { die('You do not have permission to be here'); }
对于第3种用法:
$counter = 0; while ($item = $itr->next()) { $counter++; } echo 'You scanned ' . $counter . ' items';
这样做的好处是消除了整个访问和使用这些未定义变量的后果,以及回退到引擎默认状态的用户态错误。这样我们提供了另一层保护,防止PHP程序发生了这种意外后继续运行。
这种更改也会让PHP引擎和JIT等方面不会那么复杂。
这个版本主要是针对PHP9.0的,在PHP8.2的还是警告,在以后会将这种行为提升到错误级别。
增加只读类
通过给类添加只读修饰符来声明只读类。
readonly class Test { public string $prop; }
这样做会隐式地将类的所有实例属性标记为只读。此外,它将阻止创建动态属性。
readonly class Foo { public int $bar; public function __construct() { $this->bar = 1; } } $foo = new Foo(); $foo->bar = 2; // 抛出错误,不能修改只读属性 Foo::$bar $foo->baz = 1; // 抛出错误:不能动态创建属性 Foo::$baz
可以通过增加#[AllowDynamicProperties]属性,可以不触发错误的情况下创建动态属性。
#[AllowDynamicProperties] readonly class Foo { }
一些限制:
由于是只读类,必须对属性声明类型:
readonly class Foo { public $bar; } // 以上定义会产生错误。
不能使用静态属性:
readonly class Foo { public static int $bar; } // 抛出错误: 只读属性不能声明静态类型
原文地址:https://phpreturn.com/index/a626a74a300dc5.html
原文平台:PHP武器库
版权声明:本文由phpreturn.com(PHP武器库官网)原创和首发,所有权利归phpreturn(PHP武器库)所有,本站允许任何形式的转载/引用文章,但必须同时注明出处。
推荐学习:《PHP视频教程》
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!