Migration vers PHP 8.1 - Comment corriger l'erreur obsolète de passage de null au paramètre - Renommer la fonction intégrée
P粉420868294
P粉420868294 2024-01-10 16:21:21
0
2
495

Obsolète dans PHP 8.1 null 作为参数传递给许多核心函数。我的主要问题是 htmlspecialchars(php)trim(php) 等函数,其中 null ne se convertit plus silencieusement en chaîne vide.

Pour résoudre ce problème sans utiliser beaucoup de code, j'ai essayé de renommer les fonctions intégrées d'origine et de les remplacer par des wrappers qui convertissent l'entrée de null en une chaîne (vide).

Le principal problème de cette approche est que la fonction rename_function(PECL apd) ne fonctionne plus, elle a été mise à jour pour la dernière fois en 2004 1.

J'ai besoin d'une sorte de réécriture des fonctions intégrées pour éviter d'écrire une vérification nulle à chaque fois que la fonction est appelée, ce qui rendrait tout mon code deux fois plus gros.

La seule autre solution à laquelle je peux penser est d'utiliser simplement ma fonction personnalisée, mais cela nécessite toujours de parcourir tout le code et les bibliothèques tierces dont je dispose.

Dans PHP 8.1, null n'est plus converti silencieusement en chaîne vide lorsqu'il est transmis à une fonction intégrée.


  1. https://pecl.php.net/package/apd

P粉420868294
P粉420868294

répondre à tous(2)
P粉811329034

Je pense (et en passant, les réponses existantes ont mon soutien) brossent un tableau différent de la façon dont de tels « problèmes » sont perçus et résolus. Cela ne diminue en rien le bien ou le mal de l’approche décrite, mais constitue simplement une perspective supplémentaire qui, espérons-le, sera mutuellement bénéfique. Chaque projet est différent.

Principe donné :

Eh bien, cela me semble (au début) être un problème de rapport. En ne signalant pas E_DEPRECATED.

L'avantage de ceci est que (pas seulement votre code) sait désormais que votre code est accompagné d'un avis de dépréciation. Le rapport fonctionne vraiment .

En revanche, la suppression des notifications de dépréciation peut les faire disparaître. Si vous perdez une base de code avec un avis de dépréciation, techniquement, il peut toujours être facile de récupérer de la perte (encore une fois, signalez l'avis de dépréciation), mais si la modification est étendue, cela peut maintenant être un bruit écrasant (E_TOO_MUCH_NOISE).

Alors, le code qui n'est pas silencieux est-il réellement une mauvaise chose ? Ou peut-il être transformé en avantages ? Je préfère choisir ce dernier. Quoi qu’il en soit, nous traitons déjà ces informations.

Donc, dans ce cas, mon idée est généralement de ne pas supprimer les notifications de dépréciation, mais plutôt de "faire taire" les appels de fonction. C'est facile, mais stupide dans le bon comme dans le mauvais sens :

trim($mixed);   #1  ->     @trim($mixed);   #2

Il s'agit bien entendu d'une opération qui peut être appliquée à une base de code à l'aide d'outils texte standards. Il vous montre également où l'opérateur de suppression @ a été utilisé dans le passé :

@trim($mixed);  #3  ->     @@trim($mixed);  #4

Si vous étiez un développeur PHP et regardiez un code comme celui-ci (pour les cas n°2 à n°4) dans un éditeur, ils vous crieraient immédiatement , et pour les quatre cas, attireraient au moins votre attention ($mixed).

Merci de ne pas rester silencieux, nous laissons ces endroits crier, mais pas au moment de l'exécution 1.

Contrairement à la première méthode consistant à garder le silence en ne signalant pas E_DEPRECATED 来保持沉默的方法不同,这种方法很容易丢失信息,而信息是通过使用所有 @, où les informations peuvent facilement être perdues, les informations sont enregistrées en utilisant tous les symboles

.

@Est-ce que cela aidera à résoudre le problème du bruit ? Si nous arrêtons de travailler ici, cela ne fonctionnera absolument pas. Nous allons maintenant peindre le code avec un signe p>- et décider de ne prendre aucune autre mesure, afin de pouvoir utiliser la première solution (ne pas signaler de message de dépréciation) pour le compléter sans toucher au code.

Alors quels sont ses bienfaits ? Eh bien, même si le code s'exécute désormais silencieusement

, PHP fournit toujours des messages de diagnostic. Autrement dit, il est désormais possible d'enregistrer les gestionnaires d'erreurs PHP en tant qu'écouteurs (lors de l'exécution du code).

@Seulement au niveau du code, il est facile de vérifier ces emplacements car le symbole

est (généralement) également facile à repérer dans le code. 🎜

La deuxième partie est importante car même si plusieurs endroits peuvent être affectés par la dépréciation, il ne doit pas y avoir une solution unique qui les résoudra tous (je préfère rester à l'écart des « solutions » « à taille unique » si possible), mais surtout dans le contexte de la question PHP 8.1 a changé et j'imagine qu'il y aura des besoins différents selon l'endroit où il est utilisé

Par exemple, dans le code du modèle (sortie), les types concrets ne posent pas de problème, donc la conversion en chaîne est probablement la solution préférée :

@trim($mixed);     ->     trim((string)$mixed)
@@trim($mixed);    ->     @trim((string)$mixed)

Le modèle (sortie) reste stable.

Mais pour la gestion réelle des entrées, un avis de dépréciation peut révéler des défauts potentiels réels qui méritent d'être corrigés, tels que des valeurs par défaut manquantes (ce qui rend les choses trop compliquées), une gestion peu claire des valeurs (null contre null, chaînes, booléens contre nombres). ) ) est confondu avec les tableaux et les objets en PHP) ou simplement $mixed en général.

Cette trim($mixed) est peut-être une protection de sécurité qui a été oubliée pendant de nombreuses années et qui n'a jamais été mise à niveau (de meilleures protections de sécurité sont disponibles). Pour un code comme celui-ci, je suis presque sûr de vouloir et d'exiger déjà trim($mixed) 可能是一个被遗忘多年的安全防护,从未进行过升级(有更好的安全防护可用)。对于这样的代码,我很确定我已经想要并要求 $mixed 实际上是 $string before 我使用 trim () en fait $string

avant
    d'utiliser trim (). La raison est très simple, au moins deux choses me viennent immédiatement à l'esprit :
  • trim() a) n'est plus nécessaire - il peut être supprimé (un de mes 李>correctifs
  • préférés : supprimez le code !) - ou - b) C'est
  • faire du travail avec des cordes, alors j'ai un problème parce que je ne veux rien présenter sans cordes. Le problème est que cela ne fonctionne généralement pas avec l'approche du fusil de chasse (Gießkanne, ça vous tente ?).

$mixed 进行修补是完全有效的? ''如果原始使用是字符串或nullL'application de correctifs utilisant $mixed est-elle entièrement valide ? ''Si l'utilisation originale est une chaîne ou null

seulement

. TypeError

@trim($mixed);     ->     trim($mixed ?? '')
@@trim($mixed);    ->     @trim($mixed ?? '')
Mais à part ça, un nombre comme 42, par exemple, lancera

au lieu d'un message de dépréciation. Cela fait la différence entre le code en cours d'exécution et le code qui ne l'est pas.

Il y a donc plus à maintenir ici, comme la vérification des emplacements, un regroupement supplémentaire si possible, puis l'application de correctifs plus spécialisés. Cela peut révéler des tests ou des assertions manquants, prendre un certain temps pour stabiliser l'ensemble du flux d'application, etc. @

Dans ce cas, terminez la migration du code, effectuez le clustering, gérez l'opérateur de fusion nul et effectuez les formalités administratives appropriées pour le vrai correctif. Une fois que vous avez terminé de supprimer les erreurs non évidentes à l'aide de l'opérateur de fusion nul et supprimé l'opérateur de suppression

, vous risquez de perdre ces informations si le plan de correctif ne les capture pas.

Je ne suis pas surpris de me gratter la tête ou de me frotter les yeux alors que j'ai l'air plus instruit dans ces régions. Ensuite, je me rappelle que ces erreurs ne sont pas causées par la version PHP 8.1, le changement de version ne fait que les faire apparaître (à nouveau), et parfois j'obtiens même des clusters complets d'erreurs comme capture accessoire en maintenant les versions PHP.

Cheat Sheet🎜🎜
  • (string)$mixed - Comportement précédent
  • $mixed ?? '' - 仅在 null 上抑制 TypeError Erreur
  • @ - Suppression complète des erreurs. Vous devez documenter votre base de code le cas échéant.
  • @@ - Si cela se produit, cela pourrait être un endroit intéressant à étudier.
  • 空($mixed)? '' : xxx($mixed) - Sortez les poubelles, le désordre typique de la paralysie aérienne/hybride, et recherchez les clusters, l'opportunité de simplifier grandement la base de code. Migrez vers les types scalaires (PHP 7), en introduisant le typage strict de l'intérieur vers l'extérieur, en utilisant le typage PHP "classique" et "strict" le cas échéant. Les assertions PHP 7.0 et les messages de dépréciation de PHP 8.1 le prennent bien en charge.

Gestionnaire d'erreurs

Il n'y a rien de magique dans la gestion des erreurs, c'est un standard documenté sur PHP.net (avec Exemple #1), qui agit comme un observateur des événements d'erreur et peut différencier les erreurs supprimées et non supprimées via error_reporting(php)error_reporting(php) / error_reporting(php-ini) 至少达到通常需要的级别,如果需要进行区分(在生产环境中,E_DEPRECATED 通常不是报告的一部分)。此示例性处理程序会抛出所有报告的错误,对于弃用事件以及 E_ALL 也会抛出此类错误,因此需要 @ / error_reporting(php-ini)

Au moins au niveau normalement requis, si une différenciation est nécessaire (dans un environnement de production,

ne fait généralement pas partie du rapport). Cet exemple de gestionnaire renvoie toutes les erreurs signalées, ainsi que pour les événements de dépréciation et E_ALL, donc l'opérateur de suppression

doit ne pas lancer :

set_error_handler(static function ($type, $message, $file, $line) use (&$deprecations) {
    if (!(error_reporting() & $type)) {
        // This error code is not included in error_reporting, so let it fall
        // through to the standard PHP error handler

        // capture E_DEPRECATED
        if ($type === E_DEPRECATED) {
            $deprecations[] =
                ['deprecations' => count($deprecations ?: [])]
                + get_defined_vars();
        }

        return false;
    }

    // throwing error handler, stand-in for own error reporter
    // which may also be `return false;`
    throw new ErrorException($message, $type, error_reporting(), $file, $line);
});
Des gestionnaires d'erreurs similaires peuvent être trouvés dans les exemples étendus E_USER_DEPRECATED sur 3v4l.org, y compris sur le code obsolète à signaler.

E_USER_DEPRECATED 结合使用,与上面 E_DEPRECATED

Techniquement, l'opérateur de suppression d'erreur peut être utilisé conjointement avec

de la même manière que décrit pour

ci-dessus. E_DEPRECATED

Cependant, il y a moins de contrôle sur celui-ci 🎜 et 🎜 il peut déjà être utilisé par du code tiers déjà dans les dépendances du projet. Un code comme celui-ci n'est pas rare : 🎜
@trigger_error('this. a message.', E_USER_DEPRECATED);
🎜Cela fait exactement la même chose : émettre des événements de dépréciation, mais les exclure des rapports PHP. En vous y abonnant, vous risquez de vous noyer dans le bruit. Avec 🎜 vous pouvez toujours obtenir du "bon et original" directement depuis PHP. 🎜
  1. Lorsque vous envisagez d'utiliser l'opérateur de suppression @ 错误抑制运算符的方法并对其进行评论时,IMSoP 立即举起红/黑旗(正确!),很容易将婴儿与洗澡水一起倒掉@. Dans ma réponse, son but est simplement de supprimer les notifications de dépréciation mais le résultat de l'utilisation de est qu'il supprime tous les messages de diagnostic et erreurs, même les plus fatals dans certaines versions de PHP, donc PHP se termine avec 255, aucun diagnostic supplémentaire n'est requis - soyez juste prudent et gérez. Cet opérateur est puissant. Suivez son utilisation dans la base de code et vérifiez constamment si elle répond à vos attentes. Pour les situations juridiques, pensez à utiliser un silencieux. Pour le portage/maintenance du code, marquez-le d'abord. Une fois que vous avez terminé de modifier le lot, supprimez-le à nouveau.
P粉592085423

Tout d'abord, deux choses à retenir :

  1. PHP 8.1 obsolète ces appels, ce qui ne les rend pas erreur. Le but de la dépréciation est de fournir un préavis aux auteurs pour qu'ils corrigent leur code, afin que vous et les auteurs des bibliothèques que vous utilisez puissiez résoudre les problèmes avant la sortie de PHP 9.0. Alors ne paniquez pas car tous les problèmes ne peuvent pas être résolus immédiatement et soyez patient avec les responsables de la bibliothèque qui résoudront le problème à leur rythme.
  2. Une solution rapide dans la plupart des cas consiste à utiliser l'opérateur de coalescence nul pour fournir une valeur par défaut appropriée afin que vous n'ayez pas besoin d'une longue vérification nulle à chaque fois que vous l'utilisez. Par exemple, htmlspecialchars($something) 可以替换为 htmlspecialchars($something ?? '')

Ensuite, quelques options :

  • En fonction du nombre de vos cas, vous pourrez peut-être résoudre manuellement quelques problèmes à la fois, ou ajouter ?? '' ou corriger une erreur logique, vous ne voulez pas null de toute façon.
  • Créez des fonctions personnalisées comme nullable_htmlspecialchars et recherchez et remplacez directement dans votre code.
  • Tout fichier qui crée une fonction d'espace de noms personnalisée telle que nullableoverridehtmlspecialchars;然后在添加 use function nullableoverridehtmlspecialchars; utilisera cette fonction au lieu de la fonction intégrée. Cependant, cela doit être ajouté à chaque fichier, vous aurez donc peut-être besoin d'un outil pour l'ajouter automatiquement.
  • Utilisez Rector pour ajouter automatiquement ?? '' aux appels de fonction appropriés afin que vous n'ayez pas à les modifier manuellement. Malheureusement, il ne semble pas encore y avoir de règles intégrées pour cela, vous devrez donc apprendre à écrire les vôtres.
  • Il peut être plus facile, selon vos compétences, d'utiliser l'expression régulière rechercher et remplacer pour ajouter ?? '' à des cas simples.
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal