8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

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

PositiveGuy 1月前

73 0

我正在运行 PHP 脚本并继续收到类似错误:通知:未定义变量:C:\wamp\www\mypath\index.php 中第 10 行的 my_variable_name 通知:未定义索引:my_index C:\wamp\www\...

我正在运行 PHP 脚本并继续收到类似以下错误:

注意:未定义变量:my_variable_name 在 C:\wamp\www\mypath\index.php 第 10 行

注意:未定义索引: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 的“通知:未定义变量”、“通知:未定义索引”、“警告:未定义数组键”和“通知:未定义偏移量”
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由PositiveGuy在本站《forms》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 变量可能尚未初始化。您是否正在从 post 或 get 或任何数组初始化变量?如果是这种情况,则您可能没有该数组中的字段。您正在访问。

  • @Pekka - 我注意到编辑中添加了 \'and \'通知:未定义的偏移量\'\' - 使用 \'PHP:“未定义变量”,“未定义索引”,“未定义偏移量”通知\' 不是更有意义吗(甚至去掉 PHP,因为它被标记为 \'php\')。另外,URL 被截断在

  • @Fred 我猜这两种说法都有道理。新手可能会将整行(包括“通知:\”)输入到他们的搜索查询中,我确信这是这个问题的主要流量来源。如果消息完整,则可能会提高搜索引擎的可见性

  • @Pekka 我明白。我这么说只是因为 URL 之前没有被截断,而现在被截断了

  • 此错误消息旨在 帮助 PHP 程序员在访问不存在的变量(或数组元素)时发现拼写错误或错误。因此,优秀的程序员应该:

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

    注意/警告:未定义变量

    尽管 PHP 不要求声明变量,但它还是建议声明变量,以避免某些安全漏洞或错误,因为有人可能会忘记为脚本中稍后要使用的变量赋值。在未声明变量的情况下,PHP 会发出级别错误 E_WARNING

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

    当将一个文件包含到使用相同变量名的另一个文件中时,依赖未初始化变量的默认值会产生问题。

    这意味着变量可能会从包含的文件中获取一个值,并且将使用该值而不是 null 访问未初始化的变量所期望的值,这可能会导致不可预测的结果。为避免这种情况,最好在使用前初始化 PHP 文件中的所有变量。

    处理问题的方法:

    1. p6

       //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
    • p7

      function test($param) {    return $param + 1; }$var = 0;echo test($var); // now $var's value is accessible inside through $param
    1. p8

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

      p9

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

      p10

    2. p11

    注意: 强烈建议仅实现第 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
    

    一种特殊情况是,当某个函数返回一个数组或其他值(如 null 或 ) false 。那么在尝试访问数组元素之前必须对其进行测试,例如

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

    外部数组

    对于外部数组(例如 $_POST / $_GET / $_SESSION 或 JSON 输入),情况会有所不同,因为程序员无法控制此类数组的内容。因此,检查某些键是否存在,甚至为缺失的键分配默认值都是合理的。

    • p18

        // 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  }
    • 第19页

        $agreed = $_POST['terms'] ?? false;
    • p20

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

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

    有关的:

    • 注意:未定义变量
    • 注意:未定义索引
  • @dieselpower44 几点想法:\'shut-up 运算符\' (@) 存在一些性能问题。此外,由于它会抑制特定范围内的所有错误,因此不小心使用它可能会掩盖您希望看到的消息。

  • 隐藏问题并不是解决问题的正确方法。第 2 项至第 4 项只能在生产服务器上使用,一般情况下不能使用。

  • 当使用自定义错误处理程序时,是否可以内联关闭消息(不在处理程序中)?$var = @$_GET['nonexisting']; 仍然会引起注意..

  • 为什么建议使用 1. $value = isset($_POST['value']) ? $_POST['value'] : ''; 而不是使用 4. $value = @$_POST['value'];?

  • 我不建议对数组使用 isset(),例如 $str = '111';,(我知道它应该是数组)isset($str[0]) 将返回 true。最好使用 array_key_exist() 而不是 isset()

  • 尝试这些

    Q1:此通知意味着 $varname 未在脚本的当前范围内定义。

    Q2:在使用任何可疑变量之前使用 isset()、empty() 条件效果很好。

    // 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);
    

    有关会话的说明:

    • p5

    • p6

  • 如果使用 php.ini 配置文件中的 E_NOTICE,请执行 error_reporting = (E_ALL & ~E_NOTICE)

  • 从上面的答案来看,我尝试了 isset、array_key_exists,但这些都没有用。我尝试了你的答案 .empty(),它起作用了。非常感谢!

  • 非常感谢。我已添加 \'error_reporting(E_ALL ^ E_NOTICE); \',这对我有用。

  • 错误显示 @ operator

    对于不需要的和多余的通知,可以使用专用的 @ operator 来“ 隐藏 ”未定义的变量/索引消息。

    $var = @($_GET["optional_param"]);
    
    • 通常不建议这么做。新手往往会过度使用它。
    • 它对于应用程序逻辑深处的代码(忽略不应该忽略的未声明的变量)非常不合适,例如函数参数或循环。
    • isset?: 相比,还有一个好处 ?? 。通知仍然可以被记录。并且可以使用以下方法恢复 @ 隐藏通知: set_error_handler("var_dump");
      • Additonally you shouldn't habitually use/recommend if (isset($_POST["shubmit"])) in your initial code.
      • Newcomers won't spot such typos. It just deprives you of PHPs Notices for those very cases. Add @ or isset only after verifying functionality.
      • 【【p1】】

    • @ 主要用于 $_GET / $_POST 输入参数,特别 是当它们是可选的时 .

    由于这涵盖了大多数此类问题,让我们来详细讨论一下最常见的原因:

    $_GET <未定义/code>/ $_POST / $_REQUEST 输入

    • p3

      • Is this an expected key name and present on each page request?
      • Variable names and array indicies are case-sensitive in PHP.
    • p4

      var_dump($_GET);var_dump($_POST);//print_r($_REQUEST);

      p5

    • p6

      \'浏览器

      p7

    • p8

      print_r($_SERVER);

      p9

    • p10

      p11

      p12

    • p13

      • Ensure each required input has an <input name=FOO>
      • The id= or title= attribute does not suffice.
      • A method=POST form ought to populate $_POST .
      • Whereas a method=GET (or leaving it out) would yield $_GET variables.
      • It's also possible for a form to supply action=script.php?get=param via $_GET and the remaining method=POST fields in $_POST alongside.
      • With modern PHP configurations (≥ 5.6) it has become feasible (not fashionable) to use $_REQUEST['vars'] again, which mashes GET and POST params.
    • p14

    $_FILES

    • 同样的健全性检查也适用于文件上传和 $_FILES["formname"] .
    • 此外检查 enctype=multipart/form-data
    • 以及 method=POST 您的 <form> 声明。
    • 另请参阅: PHP 未定义索引错误 $_FILES?

    $_COOKIE

    • $_COOKIE 数组永远不会在之后立即填充 setcookie() ,而只会在任何后续 HTTP 请求时填充。
    • 此外,它们的有效性超时,它们可能被限制在子域或单独的路径中,用户和浏览器可以拒绝或删除它们。
  • 如果您好奇性能影响是什么,这篇文章很好地总结了它,derickrethans.nl/...。

  • @GajusKuizinas 自 2009 年以来发生了一些变化,特别是 php.net/ChangeLog-5.php#5.4.0 彻底改变了结果(参见“Zend Engine,性能”和“(静音)运算符”)。

  • 谢谢@mario,很有趣。现在,如果有人足够优秀,可以对两者进行基准测试... 3v4l.org/CYVOn/perf#tabs 3v4l.org/FLp3D/perf#tabs 根据此测试,似乎是相同的(请注意比例会发生变化)。

  • 通常是因为‘糟糕的编程’,现在或以后可能会出现错误。

    1. 如果是错误,请先对变量进行正确赋值:$varname=0;
    2. 如果确实只是有时定义,请 if (isset($varname)) 在使用它之前
    3. 如果是因为你拼写错误,只需纠正即可
    4. 甚至可以关闭 PHP 设置
返回
作者最近主题: