「通知: 未定義の変数」、「通知: 未定義のインデックス」、「警告: 未定義の配列キー」、および「通知: 未定義のオフセット」を PHP で表示する 質問する

「通知: 未定義の変数」、「通知: 未定義のインデックス」、「警告: 未定義の配列キー」、および「通知: 未定義のオフセット」を PHP で表示する 質問する

PHP スクリプトを実行していますが、次のようなエラーが引き続き発生します:

注意: C:\wamp\www\mypath\index.php の 10 行目に未定義の変数: my_variable_name があります

注意: 未定義のインデックス: my_index C:\wamp\www\mypath\index.php の 11 行目

警告: C:\wamp\www\mypath\index.php の 11 行目に未定義の配列キー "my_index" があります

10 行目と 11 行目は次のようになります。

echo "My variable value is: " . $my_variable_name;
echo "My index value is: " . $my_array["my_index"];

これらのエラーメッセージの意味は何ですか?

なぜ突然表示されるのでしょうか? 私は長年このスクリプトを使用してきましたが、これまで何の問題もありませんでした。

どうすれば修正できますか?


これは、問題を何度も説明しなくても済むように、重複としてリンクするための一般的な参照質問です。この問題に関する実際の回答のほとんどが非常に具体的であるため、これが必要であると感じています。

関連するメタディスカッション:

ベストアンサー1

このエラー メッセージは、PHP プログラマーが存在しない変数 (または配列要素) にアクセスするときにタイプミスや間違いを見つけるのに役立ちます。したがって、優れたプログラマーは次のことを行います。

  1. すべての変数または配列キーが、使用される時点ですでに定義されていることを確認します。関数内で変数を使用する必要がある場合は、その変数をパラメーターとしてその関数に渡す必要があります。
  2. このエラーに注意を払い、他のエラーと同様に修正を進めます。スペルミスや、何らかの手順で返されるべきデータが返されなかったことを示している可能性があります。
  3. プログラマーの制御下にないまれな場合にのみ、このエラーを回避するコードを追加できます。ただし、決して無意識に行う習慣であってはなりません。

通知/警告: 未定義の変数

PHP では変数の宣言は必須ではありませんが、スクリプトの後半で使用される変数に値を指定し忘れることによるセキュリティ上の脆弱性やバグを回避するために宣言することを推奨しています。宣言されていない変数の場合、PHP はE_WARNINGレベルのエラーを発行します。

この警告は、プログラマーが変数名のスペルミスや同様のミス(条件内で変数に偽と評価される値が割り当てられているなど)を見つけるのに役立ちます。また、初期化されていない変数には他にも問題があります。述べましたPHPマニュアルでは、

初期化されていない変数のデフォルト値に依存することは、同じ変数名を使用する別のファイルに 1 つのファイルをインクルードする場合に問題になります。

つまり、変数はインクルードされたファイルから値を取得し、その値が、null初期化されていない変数へのアクセスで予想される値の代わりに使用されることになり、予期しない結果につながる可能性があります。これを回避するには、PHP ファイル内のすべての変数を使用前に初期化しておくのが最適です。

この問題に対処する方法:

  1. 推奨:使用する前にすべての変数を宣言します。こうすることで、存在しない変数を使用しようとして実際に間違いを犯した場合にのみこのエラーが表示されます。これが、このエラー メッセージが存在する理由です。

     //Initializing a variable
     $value = ""; //Initialization value; 0 for int, [] for array, etc.
     echo $value; // no error
     echo $vaule; // an error pinpoints a misspelled variable name
    
  • 変数が定義されているが関数内では見えない特殊なケース。PHPの関数には独自の変数のスコープ関数内で外部の変数を使用する必要がある場合は、その値を関数のパラメータとして渡す必要があります。

    function test($param) {
        return $param + 1; 
    }
    $var = 0;
    echo test($var); // now $var's value is accessible inside through $param
    
  1. null 合体演算子を使用してエラーを抑制します。ただし、この方法では PHP が間違った変数名の使用について通知できないことに注意してください。

     // Null coalescing operator
     echo $value ?? '';
    

    古いPHPバージョン(< 7.0)では、三項演算子付きのisset()が使用できます。

     echo isset($value) ? $value : '';
    

    ただし、これは本質的にはエラー抑制であり、特定のエラーのみを対象としていることに注意してください。そのため、初期化されていない変数をマークすることで、PHP がサポートできなくなる可能性があります。

  2. エラーを抑制するには@ 演算子歴史的な理由でここに残しましたが、真剣に言えば、そんなことは起こるべきではありません。

注:ポイント 1 のみを実装することを強くお勧めします。

通知: 未定義のインデックス / 未定義のオフセット / 警告: 未定義の配列キー

この通知/警告は、ユーザー (または PHP) が配列の未定義のインデックスにアクセスしようとしたときに表示されます。

内部配列

コード内で定義されている内部配列を扱う場合も、考え方はまったく同じです。つまり、使用前にすべてのキーを初期化するだけです。こうすることで、このエラーは本来の目的である、つまりプログラマーにコードの間違いを通知する役割を果たします。したがって、アプローチは同じです。

推奨:配列要素を宣言します。

    //Initializing a variable
    $array['value'] = ""; //Initialization value; 0 for int, [] for array, etc.
    echo $array['value']; // no error
    echo $array['vaule']; // an error indicates a misspelled key

特別なケースとして、関数が配列か、またはなどの他の値を返す場合が挙げられますnullfalseその場合、配列要素にアクセスする前にテストする必要があります。

$row = $stmt->fetch();
if ($row) { // the record was found and can be worked with
    echo $row['name']; 
}

配列の外側

外部配列 ( $_POST//や JSON 入力など) の場合、プログラマーはそのような配列の内容を制御できないため$_GET$_SESSION状況は少し異なります。そのため、キーの存在を確認したり、欠落しているキーにデフォルト値を割り当てたりすることが正当化される場合があります。

  • PHPスクリプトにHTMLフォームが含まれている場合、最初の読み込み時にはフォームの内容がないのは当然です。したがって、そのようなスクリプトではフォームが送信されたかどうかを確認する必要があります。

      // for POST forms check the request method
      if ($_SERVER['REQUEST_METHOD'] === 'POST') {
          // process the form
      }
      // for GET forms / links check the important field
      if (isset($_GET['search'])) {
          // process the form
      }
    
  • チェックボックスなどの一部のHTMLフォーム要素は、チェックされていない場合はサーバーに送信されません。この場合、デフォルト値を割り当てるためにnull結合演算子を使用するのが妥当です。

      $agreed = $_POST['terms'] ?? false;
    
  • オプションのクエリ文字列要素またはクッキーも同様に扱われるべきである

      $limit = $_GET['limit'] ?? 20;
      $theme = $_COOKIE['theme'] ?? 'light';
    

しかし、割り当てはスクリプトの最初に行う必要があります。すべての入力を検証し、それをローカル変数に割り当て、コード全体でそれらを使用します。そのため、アクセスするすべての変数は意図的に存在することになります。

関連している:

おすすめ記事