検索

ホームページ  >  に質問  >  本文

PHP 8.1 への移行 - 非推奨のパラメーターに null を渡すエラーを修正する方法 - ビルドイン関数の名前を変更する

PHP 8.1 では、多くのコア関数に引数として null を渡すことが非推奨になりました。私の主な問題は、htmlspecialchars(php)trim(php) のような関数に関するもので、nullsilently で null に変換されなくなります。文字列。

多くのコードを使用せずにこの問題を解決するために、元の組み込み関数の名前を変更し、入力を null から (空の) 文字列に変換するラッパーに置き換えてみました。

このアプローチの主な問題は、関数 rename_function(PECL apd) が機能しなくなり、最後に更新されたのが 2004 1 であることです。

関数が呼び出されるたびに null チェックを記述してすべてのコードが 2 倍大きくなるのを避けるために、組み込み関数を何らかの形で書き直す必要があります。

他に思いつく唯一の解決策は、カスタム関数を使用することですが、それでも、私が持っているすべてのコードとサードパーティのライブラリを調べる必要があります。

PHP 8.1 では、組み込み関数に渡されたときに、null が暗黙的に空の文字列に変換されなくなりました。


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

P粉420868294P粉420868294322日前498

全員に返信(2)返信します

  • P粉811329034

    P粉8113290342024-01-11 15:36:30

    私は、そのような「問題」がどのように見られ、解決されるかについて、別の絵を描いていると思います (補足として、既存の回答は私の支持を得ています)。これは、概説したアプローチの正誤を減じるものではなく、相互に有益であることが期待される追加の視点にすぎません。すべてのプロジェクトは異なります。

    与えられた前提:

    さて、これは (最初は) レポートの問題であるように私には思えます。 #E_DEPRECATED を報告しないことにより。

    これの利点は、(コードだけでなく) コードに非推奨の通知が付いていることを認識できることです。レポート

    は確かに有効です

    一方、非推奨通知を抑制すると、非推奨通知が表示されなくなる可能性があります。非推奨通知によってコード ベースを失った場合、技術的にはまだ簡単に損失から回復できる可能性があります (再度、非推奨通知を報告します)。しかし、変更が延長されると、圧倒的なノイズ (E_TOO_MUCH_NOISE) になる可能性があります。

    では、コードがサイレントでないことは実際には悪いことなのでしょうか?それとも利益に変えることができるのでしょうか?私なら後者を選びたいと思います。いずれにせよ、私たちはすでにこの情報を処理しています。

    したがって、

    このケース では、私の考えは、通常、非推奨通知を抑制せず、関数呼び出しを「沈黙」させることです。簡単ですが、良い意味でも悪い意味でも愚かです: リーリー

    これはもちろん、標準のテキスト ツールを使用してコード ベースに適用できる操作です。また、

    @ 抑制演算子が過去に使用された場所も表示されます: リーリー

    あなたが PHP 開発者で、このようなコードをエディターで見ている場合 (ケース #2 ~ #4)、すぐに

    叫び声を上げます 4 つのケースすべてにおいて、少なくとも、あなたの興味を引くでしょう。注意してください ($混合)。

    黙っていてくれてありがとう。実行時ではなく、

    1 だけで、これらの場所に 悲鳴を上げさせます。

    E_DEPRECATED

    を報告しないことで沈黙を保つ最初の方法とは異なり、この方法では情報が簡単に失われる可能性がありますが、情報はすべての @ シンボルを使用することで保持されます。 それは騒音問題の解決に役立ちますか?ここで働くことをやめたら、それはまったくうまくいきません。次に、コードを

    #@

    - 記号でペイントし、それ以上のアクションは行わないことにします。これにより、最初の解決策 (非推奨メッセージが報告されない) を使用して、コードに触れることなく解決を完了できます。 それでは、その利点は何でしょうか?コードは サイレントに実行されますが、PHP は依然として診断メッセージを提供します。つまり、(コードの実行中に) PHP エラー ハンドラーをリスナーとして登録できるようになりました。

    コード レベルでのみ、@

    シンボルは (通常は) コード内でも簡単に見つけられるため、これらの場所を確認するのは簡単です。

    パート 2

    が重要です。なぜなら、複数の場所が非推奨の影響を受ける可能性がある一方で、すべてを修正する 1 つのソリューションがあってはなりません (私は、「1 つのサイズですべてに適合する」ソリューション シナリオは避けたいと考えています)。 " (可能であれば) しかし、特に質問の文脈では、PHP 8.1 は変更されており、使用される場所に応じて異なるニーズがあることが想像できます。

    たとえば、テンプレート コード (出力) では、具象型は問題ではないため、文字列に変換することが推奨される解決策である可能性が最も高くなります。 リーリー テンプレート (出力) は安定したままです。

    しかし、実際の入力処理に関しては、非推奨の通知によって、デフォルト値の欠落 (物事が過度に複雑になる)、不明瞭な値の処理 (null と null、文字列、ブール値の区別など) など、修正する価値のある実際の潜在的な欠陥が明らかになる可能性があります。数値)、PHP のオブジェクトを含む配列)、または一般的な $mixed を使用します。

    このような trim($mixed) は、長年にわたって忘れられ、アップグレードされていないセキュリティである可能性があります (より優れたセキュリティが利用可能です)。このようなコードの場合、$mixed が実際には $string であることをすでに望んでおり、要求していると確信しています。 trim ()# を使用します。 ##。理由は非常に単純で、少なくとも次の 2 つのことが直接思い浮かびます。 a) trim()

    はもう必要ありません - 削除できます (
      お気に入りの
    • 修正の 1 つ: コードを削除してください!) - または - b) 文字列の処理を行っていますが、文字列以外のものを存在させたくないので問題が発生します。問題は、一般的にショットガンのアプローチでは機能しないことです (ギースカンネ、誰か?)。
    • $mixed を使用したパッチ適用は完全に有効ですか? ''
    元の使用法

    が文字列または null の場合は のみ。 リーリー しかし、そうでない場合、たとえば 42 のような数値は、非推奨メッセージの代わりに TypeError をスローします。これにより、実行中のコードと実行されていないコードが区別されます。

    つまり、場所の確認、可能であればさらなるクラスタリング、より特殊な修正の適用など、ここで維持する必要があることはさらにあります。欠落しているテストやアサーションが明らかになったり、アプリケーション フロー全体を安定させるのに時間がかかる場合などが考えられます。 この場合、コードの移行を完了し、クラスタ化して、null マージ演算子を処理し、実際の修正に必要な適切な事務処理を行います。 Null 合体演算子を使用して非明白なエラーの抑制を完了し、

    @

    抑制演算子を削除した後、修復計画でこの情報が取得されないと、この情報が失われる可能性があります。

    これらの分野でより知識があるように見えるときに、頭をかいたり目をこすったりすることに私は驚きません。そして、これらのエラーは PHP 8.1 バージョンが原因ではなく、バージョンの変更によって (再び) エラーが発生するだけであり、場合によっては、PHP のバージョンを維持することによって完全なエラーのクラスターが副次的に発生することさえある、と自分に言い聞かせます。 ######カンニングペーパー######

    (string)$mixed

    - 以前の動作

    $mixed ?? ''

    -
      null
    • でのみ TypeError エラー
    • を抑制します
    • #@ - 完全なエラー抑制。該当する場合は、コードベースを文書化する必要があります。 @@ - これが起こった場合、これは調べてみるのが興味深い場所かもしれません。
    • 空 ($mixed)? '' : xxx($mixed) - 典型的な空の麻痺/混合混乱であるガベージを取り除き、コード ベースを大幅に簡素化する機会を利用してクラスターを探します。スカラー型 (PHP 7) に移行し、必要に応じて PHP の「クラシック」および「厳密な」型付けを使用して、徹底的な厳密な型付けを導入します。 PHP 7.0 アサーションと PHP 8.1 非推奨メッセージは、これを適切にサポートしています。
    • エラーハンドラ
    • エラー処理には魔法はありません。エラー処理は PHP.net で文書化された標準 (Example #1) であり、エラー イベントのオブザーバーとして機能し、エラー イベントを区別できます。抑制されたエラーと抑制されていないエラーは、error_reporting(php) / error_reporting(php-ini) を介して、少なくとも通常必要なレベルまで処理されます。 , 区別する必要がある場合 (運用環境では、通常、E_DEPRECATEDreport の一部ではありません)。このサンプル ハンドラーは、非推奨イベントおよび E_ALL についても含め、報告されたすべてのエラーをスローするため、@ 抑制演算子はスローしないようにする必要があります。

      リーリー

      同様のエラー ハンドラーは、報告される非推奨のコードを含む、3v4l.org の拡張例 にあります。

      E_USER_DEPRECATED

      技術的には、エラー抑制演算子は、上で概説した E_DEPRECATED と同じ方法で E_USER_DEPRECATED と組み合わせて使用​​できます。

      ただし、これを制御する機能はあまりなく、 および すでにプロジェクトの依存関係にあるサードパーティのコードによってすでに使用されている可能性があります。次のようなコードは珍しいことではありません:

      リーリー

      これはまったく同じことを行います。非推奨イベントを発行しますが、それらを PHP レポートから除外します。これらを購読すると、ノイズに溺れてしまう可能性があります。 E_DEPRECATED を使用すると、いつでも PHP から直接「優れたオリジナル」を取得できます。


      1. IMSoP は、エラー抑制オペレーターへの @ アプローチを検討し、それについてコメントすると、すぐに赤/黒のフラグを立てます (正しく!)。赤ちゃんをお風呂の水と一緒に捨てるのは簡単です@ 抑制演算子。私の答えでは、その目的は非推奨通知を抑制することだけです しかし、 これを使用した結果、 すべての 診断メッセージとエラー (一部の PHP バージョンでは致命的なメッセージやエラーも) が抑制されます。そのため、PHP はそれ以上の診断を行わずに 255 で終了します。慎重に handle を処理してください。この演算子は強力です。コードベースでの使用状況を追跡し、ベースライン/期待を満たしているかどうかを常に確認します。法的な状況に備えて、サイレンサーの使用を検討してください。コードを移植/保守する場合は、最初にコードにマークを付けます。バッチの編集が完了したら、再度削除します。

      返事
      0
  • P粉592085423

    P粉5920854232024-01-11 00:24:47

    まず、覚えておくべき 2 つのこと:

    1. PHP 8.1 非推奨 これらの呼び出しは、エラー にはなりません。非推奨の目的は、作成者にコードを修正するよう事前に通知し、ユーザーと使用するライブラリの作成者が PHP 9.0 がリリースされる前に問題を修正できるようにすることです。すべての問題をすぐに修正できるわけではないのでパニックにならず、ライブラリのメンテナがすぐに問題を修正してくれるので辛抱強く待ちましょう。
    2. ほとんどの場合の簡単な解決策は、 null 合体演算子 を使用して適切なデフォルト値を提供し、使用するたびに長い null チェックを行う必要がないようにすることです。たとえば、htmlspecialchars($something) は、htmlspecialchars($something ?? '')
    3. に置き換えることができます。

    次に、いくつかのオプションがあります:

    • ケースの数に応じて、一度にいくつかの問題を手動で修正したり、?? '' を追加したり、論理エラーを修正したりできる場合がありますが、とにかく null は必要ありません。
    • nullable_htmlspecialchars などのカスタム関数を作成し、コード内で直接検索して置換します。
    • nullableoverride\htmlspecialchars
    • などのカスタム名前空間関数を作成します。その後、任意のファイルに use function nullableoverride\htmlspecialchars; を追加すると、その関数がビルドされた関数の代わりに使用されます。 -in関数。ただし、これはすべてのファイルに追加する必要があるため、自動的に追加するツールが必要になる場合があります。 #Rector
    • を使用すると、適切な関数呼び出しに
    • ?? '' が自動的に追加されるため、手動で編集する必要はありません。残念ながら、これに関する組み込みルールはまだないようなので、独自のルールを作成する方法を学ぶ必要があります。 スキルによっては、正規表現の検索と置換を使用して、単純なケースに ?? ''
    • を追加する方が簡単かもしれません。
    • 返事
      0
  • キャンセル返事