首页  >  问答  >  正文

使用 PHP 的“注意:未定义的变量”、“注意:未定义的索引”、“警告:未定义的数组键”和“注意:未定义的偏移量”

<p>我正在运行 PHP 脚本并继续收到如下错误:</p> <blockquote> <p>注意:未定义的变量:第 10 行 C:wampwwwmypathindex.php 中的 my_variable_name</p> <p>注意:未定义索引:my_index C:wampwwwmypathindex.php 第 11 行</p> <p>警告:第 11 行 C:wampwwwmypathindex.php 中未定义数组键“my_index”</p> </blockquote> <p>第 10 行和第 11 行如下所示:</p> <pre class="brush:php;toolbar:false;">echo "My variable value is: " . $my_variable_name; echo "My index value is: " . $my_array["my_index"];</pre> <p>这些错误消息的含义是什么?</p> <p>为什么他们会突然出现?我使用这个脚本很多年了,从来没有遇到过任何问题。</p> <p>如何修复它们?</p> <hr /> <blockquote> <p><sub><strong>这是一个一般参考问题</strong>,人们可以链接到重复的问题,而不必一遍又一遍地解释问题。我觉得这是必要的,因为这个问题的大多数现实答案都非常具体。 </sub></p> <p><sub>相关元讨论:</sub></p> <ul> <li><sub>对于重复的问题该怎么办?</sub></li> <li><sub>“参考问题”有意义吗?</sub></li> </ul> </blockquote><p><br /></p>
P粉851401475P粉851401475423 天前483

全部回复(2)我来回复

  • P粉644981029

    P粉6449810292023-08-24 11:13:56

    试试这些

    // recommended solution for recent PHP versions
    $user_name = $_SESSION['user_name'] ?? '';
    
    // pre-7 PHP versions
    $user_name = '';
    if (!empty($_SESSION['user_name'])) {
         $user_name = $_SESSION['user_name'];
    }

    或者,作为一个快速但肮脏的解决方案:

    // not the best solution, but works
    // in your php setting use, it helps hiding site wide notices
    error_reporting(E_ALL ^ E_NOTICE);

    关于会话的注意事项:

    回复
    0
  • P粉787934476

    P粉7879344762023-08-24 10:41:30

    此错误消息旨在帮助 PHP 程序员在访问不存在的变量(或数组元素)时发现拼写错误或错误。所以一个好的程序员:

    1. 确保每个变量或数组键在使用时都已定义。如果需要在函数内部使用变量,则必须将其作为参数传递给该函数。
    2. 注意此错误并继续修复它,就像处理任何其他错误一样。它可能表示存在拼写错误或某些过程未返回应有的数据。
    3. 只有在极少数情况下,当事情不受程序员控制时,才可以添加代码来避免此错误。但这绝不应该是一种盲目的习惯。

    通知/警告:未定义的变量

    虽然 PHP 不需要变量声明,但它确实建议这样做,以避免一些安全漏洞或错误,即人们会忘记为稍后在脚本中使用的变量赋值。 PHP 在未声明变量的情况下会发出 E_WARNING 级别的错误。

    此警告可帮助程序员发现拼写错误的变量名称或类似类型的错误(例如在评估为 false 的条件内为变量分配了值)。此外,未初始化的变量还可能存在其他问题。正如 PHP 手册中所述

    这意味着变量可能会从包含的文件中获取值,并且将使用该值而不是预期访问未初始化变量的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. 使用空合并运算符抑制错误。但请记住,这样 PHP 将无法通知您使用了错误的变量名称。

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

      对于古老的 PHP 版本(< 7.0),可以使用带有三元的 isset()< 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 / $_GET / $_SESSION 或 JSON 输入),情况有点不同,因为程序员无法控制此类数组的内容。因此,检查某些键是否存在,甚至为丢失的键分配默认值都是合理的。

    • 当 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 表单元素(例如复选框)如果未选中,则不会发送到服务器。在这种情况下,有理由使用空合并运算符来分配默认值

      $agreed = $_POST['terms'] ?? false;
    • 可选的 QUERY STRING 元素或 cookie 应以相同的方式处理

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

    但是分配应该在脚本的一开始就完成。 验证所有输入,将其分配给局部变量,并在代码中始终使用它们。因此,您要访问的每个变量都会故意存在。

    相关:

    回复
    0
  • 取消回复