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

既存のコードベースを PHP 8.1 に更新: Null 値を含む非 null 許容内部関数パラメーターの処理

php 8.1 と互換性を持たせるためにコードのアップグレードを開始したところです。潜在的な null 値を内部関数に渡しているコード スニペットがたくさんあります。

リーリー

$row は、NULL 値を持つ可能性のあるソース (クエリなど) から取得されます。これにより、非推奨の警告が生成される場合があります。この場合:

非推奨: strlen(): string 型のパラメータに null を渡すことは非推奨です #1 ($string)

グローバル検索と置換を実行できる場所を修正するなど、このコードのアップグレードを処理する最も簡単で時間効率の良い方法を探しています。機能を変更せずに内部関数に渡す変数を型キャストしているようです。

リーリー

この方法でエンコードする道徳的な側面とは別に、この内部機能アプローチに何か問題はありますか? (コードを完全に書き換えて null 値を別の方法で処理する以外に) より良い方法はありますか?私はこのソリューションが v7.4 と下位互換性があることを好みますが、おそらく 8.0 と互換性があると思います。

ユーザー定義関数には他のオプションがあることはわかっています。

P粉344355715P粉344355715375日前769

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

  • P粉436410586

    P粉4364105862023-11-01 11:49:53

    「このコードのアップグレードを処理する最も簡単で時間効率の高い方法」に関する質問に答えます。

    つまり、それはできません。


    まず背景について説明します...

    15% の開発者が strict_types=1 を使用しているため、あなたは使用していない大多数の一人になります。

    現在この問題は 無視できます (非推奨) が、PHP 9.0 ではこれを致命的な型エラーにすることで多くの問題が発生します。

    とはいえ、引き続き NULL 接続文字列を使用できます:

    リーリー

    NULL を空の文字列と比較することはできます:

    リーリー

    また、計算に NULL を使用することもできます (0 として扱われます):

    リーリー

    NULL を出力/エコーすることはできます:

    リーリー

    sprintf() に NULL を渡し、%s を使用して空の文字列に強制することもできます (例: ) リーリー

    のような他の値を強制することもできます (ルールに従ってください)。 リーリー

    NULL 強制はそれ以来、最初からこのように機能しており、それも文書化されています:


    とにかく、修正するために...

    最初の 部分では、更新する必要があるコードを見つけようとします。

    これは、NULL

    をこれらの関数引数のいずれかに渡すことができる場合に発生します。

    少なくとも

    335 パラメータがこれによって影響を受けます。

    追加の

    104 もありますが、これは少し怪しいです ; および NULL に問題がある 558 は、どこを修正する必要がありますか (例: define(NULL, ')価値')###。 詩篇

    は、これに役立つ唯一のツールです。

    詩篇は非常に高い検査レベル (1、2、または 3) である必要があります。

    また、ベースラインを使用して問題を無視することはできません (開発者が既存のプロジェクトに静的分析を導入して、新規/編集されたコードのみをチェックする手法)。

    これまでに静的解析ツールを使用したことがない場合 (心配しないでください。開発者の

    33% のみに推奨されています

    )、コードの変更 (開始点は ) に多くの時間がかかることが予想されます。レベル 8、最大緩め、その後ゆっくり増加)。

    これらの問題を見つけるために PHPStan、Rector、PHP CodeSniffer、PHP CS Fixer、または PHPCompatibility を使用することはできません (出典)。


    各質問を見つけたら、2 番目の 部分を編集します。

    問題が発生する可能性が最も低い場所は、シンクを交換することです。たとえば、

    リーリー

    あるいは、変数のソースまで遡って、そもそも変数が NULL に設定されないようにしてみることもできます。

    次に、NULL の非常に一般的なソースをいくつか示します:

    リーリー

    これらの関数の一部では、デフォルト値を指定するために 2 番目のパラメーターが必要です。または、事前に strval() を使用することもできます...ただし、コードが < code>($a を渡す可能性があることに注意してください) = == NULL)、そしてそれを壊したくないでしょう。

    多くの開発者は、変数の一部に NULL を含めることができることを認識していません。たとえば、ネットワークの問題やブラウザ拡張機能などにより、(作成した)

    (作成した) 入力フィールドが常にすべて送信されることを期待しています。ユーザーがブラウザで DOM/URL などを編集すると、この現象が起こらない場合があります。


    私は一年のほとんどをこの問題に取り組んできました。

    私はこの問題を解決するために 2 つの RFC を書き始めました。 1 つ目は、一部の関数を更新して NULL を受け入れるようにすることです (これは、strict_types を使用する開発者を混乱させるため、理想的ではありません)。 2 つ目の RFC は、この場合に NULL を強制し続けることを許可することです。 ... ..しかし、私はそれを投票にかけませんでした。なぜなら、大量の否定的なフィードバックを受け取ったばかりであり、この問題が修正できない理由を将来説明するためにその拒否が参照されることを望まなかったからです(そして 最初の変更はかろうじてディスカッション 、これです)。

    NULL は「スカラー値」として扱われないため、異なる方法で処理されるようです。多くの開発者はこの区別を気にしていないと思いますが、時々問題になることがあります。

    私が協力した開発者のほとんどはこの問題を無視しています (後で修正することを望んでいますが、これはおそらく最善のアイデアではありません); 例:

    リーリー

    strval()prune(strval($search)) のようにあらゆるものに適用しようとしているチームがあります。しかし、1 年以上経ってもまだ問題が発生しています (8.1 alpha 1 でテストしているとのことでした)。

    私が検討しているもう 1 つのオプションは、これらの ~335 個の関数すべてを名前空間で null 許容として再定義するライブラリを作成することです (例:

    ) リーリー

    その後、開発者はライブラリをインクルードし、名前空間自体を使用します:

    リーリー

    返事
    0
  • P粉087074897

    P粉0870748972023-11-01 09:34:02

    null のケースを明示的に処理しようとしている場合、もう少しきれいな修正は、strlen($row ?? '') で「null 合体演算子」を使用することです。 。

    ほとんどの場合、この 2 つはおそらく同等ですが、strict_types=1 が有効な場合、値が文字列に変換できる別の型である場合、動作が異なります。相違点:

    リーリー

    一方、?? 演算子は === null ではなく isset に基づいているため、 は未定義であることに注意してください 変数の動作が異なります:

    リーリー

    このケースに関心がある場合、古い動作に最も直接的に相当するものはより冗長です:

    リーリー

    返事
    0
  • キャンセル返事