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

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

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

注意:未定义的索引:my_index C:\wamp\www\mypath\index.php在第 11 行

警告:未定义的数组键“my_index”在第 11 行的 C:\wamp\www\mypath\index.php

第 10 行和第 11 行如下所示:

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

这些错误消息的含义是什么?

为什么它们会突然出现?我曾经使用这个脚本很多年,我从来没有遇到过任何问题。

如何修复它们?


这是一个一般参考问题,供人们作为重复链接,而不必一遍又一遍地解释问题。我觉得这是必要的,因为关于这个问题的大多数现实世界的答案都非常具体。

相关元讨论:


答案 1

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

PHP手册的广阔智慧中:

在将一个文件包含在使用相同变量名称的另一个文件中的情况下,依赖未初始化变量的默认值是有问题的。打开register_globals也是一个主要的安全风险E_NOTICE级别错误是在使用未初始化的变量的情况下发出的,但在将元素追加到未初始化的数组的情况下则不会。isset() 语言构造可用于检测变量是否已初始化。此外,更理想的是 empty() 的解决方案,因为如果变量未初始化,它不会生成警告或错误消息。

来自 PHP 文档

如果变量不存在,则不会生成警告。这意味着 empty() 本质上是简洁的等价物 !isset($var) || $var == false

这意味着您只能用于确定变量是否已设置,此外,它还会根据以下、或 检查变量。empty()00.0"""0"nullfalse[]

例:

$o = [];
@$var = ["",0,null,1,2,3,$foo,$o['myIndex']];
array_walk($var, function($v) {
    echo (!isset($v) || $v == false) ? 'true ' : 'false';
    echo ' ' . (empty($v) ? 'true' : 'false');
    echo "\n";
});

3v4l.org 在线 PHP 编辑器中测试上述代码段

尽管 PHP 不需要变量声明,但它确实建议这样做,以避免一些安全漏洞或错误,在这些情况下,人们会忘记为稍后将在脚本中使用的变量赋值。PHP 在未声明的变量的情况下所做的是发出一个非常低级别的错误,一个甚至默认不报告的错误,但手册建议在开发过程中允许E_NOTICE

处理问题的方法:

  1. 推荐:声明变量,例如,当您尝试将字符串追加到未定义的变量时。或者使用 isset() / !empty() 在引用它们之前检查它们是否已声明,如:

    //Initializing variable
    $value = ""; //Initialization value; Examples
                 //"" When you want to append stuff later
                 //0  When you want to add numbers later
    //isset()
    $value = isset($_POST['value']) ? $_POST['value'] : '';
    //empty()
    $value = !empty($_POST['value']) ? $_POST['value'] : '';
    

从 PHP 7.0 开始,这已经变得更加干净,现在您可以使用 null 合并运算符

    // Null coalesce operator - No need to explicitly initialize the variable.
    $value = $_POST['value'] ?? '';
  1. 为E_NOTICE设置自定义错误处理程序,并将消息从标准输出重定向(可能重定向到日志文件):

    set_error_handler('myHandlerForMinorErrors', E_NOTICE | E_STRICT)
    
  2. 禁止E_NOTICE报告。排除的快速方法是:E_NOTICE

    error_reporting( error_reporting() & ~E_NOTICE )
    
  3. 使用 @ 运算符禁止显示错误。

注意:强烈建议仅实现第 1 点。

注意:未定义的索引/未定义的偏移量/警告:未定义的数组键

当您(或 PHP)尝试访问数组的未定义索引时,会出现此通知/警告。

处理问题的方法:

  1. 在访问索引之前,请检查索引是否存在。为此,您可以使用 isset()array_key_exists()

    //isset()
    $value = isset($array['my_index']) ? $array['my_index'] : '';
    //array_key_exists()
    $value = array_key_exists('my_index', $array) ? $array['my_index'] : '';
    
  2. 语言构造 list() 在尝试访问不存在的数组索引时可能会生成以下内容:

    list($a, $b) = array(0 => 'a');
    //or
    list($one, $two) = explode(',', 'test string');
    

两个变量用于访问两个数组元素,但是只有一个数组元素 index ,因此这将生成:0

注意:未定义的偏移量:1

#$_POST / $_GET / $_SESSION变量

使用 或 时,上述通知经常出现。对于,您只需要在使用它们之前检查索引是否存在。因为您必须确保会话以session_start()启动,并且索引也存在。$_POST$_GET$_SESSION$_POST$_GET$_SESSION

另请注意,所有 3 个变量都是超全局变量,并且是大写的。

相关:


答案 2

试试这些

问题 1:此通知表示$varname未在脚本的当前范围内定义。

问题 2:在使用任何可疑变量之前,先使用 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);

关于会话的说明: