"注意: 未定义的变量"、"注意: 未定义的索引" 和 "注意: 未定义的偏移量" 使用 PHP

共27个回答,已解决, 标签: php arrays variables warnings undefined-index

我正在运行一个 PHP 脚本, 并继续收到错误, 如:

注意: 未定义的变量: c:\ Wamt\\ w\ Mypmthth\ sindex. php 中的我的 _ 变量 _ name 在第 10 行

注意: 未定义的索引: 我的 _ index C:\ Wamp\\ w\ Mypmthm\ sindex. php 在第 11 行

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

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

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

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

如何修复它们?

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

相关的元讨论:

第1个答案(采用)

注意: 未定义的变量

Php 手册的巨大智慧:

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

php 文档:

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

这意味着您只能使用 empty() 来确定是否设置了变量, 此外, 它还根据以下内容检查变量 0,"",null

例子:

$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 coalesce operator - No need to explicitly initialize the variable.
    $value = $_POST['value'] ?? '';
    
  2. 为 E _ NOTICE 设置自定义错误处理程序, 并将消息从支架上重定向

第2个答案

试试这些

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

问题 2: 使用条件 ()、空 () 条件之前, 使用任何可疑变量效果良好。

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

有关会话的说明:

第3个答案

错误显示 @ 运算符

对于不需要和多余的通知, 可以使用专用 @ 运算符"隐藏" 未定义的可变/索引消息。

$var = @($_GET["optional_param"]);
  • 这通常是不鼓励的。新来者往往过度使用它。
  • 在应用程序逻辑的深处进行代码编写 (忽略不应该使用的未声明变量) 是非常不合适的, 例如函数参数, 或者是循环中的变量。
  • 然而, 有一个上行 isset?: 的东西或 ?? 超级压抑。仍可记录通知。你可能会复活 @ 隐藏的通知与:set_error_handler("var_dump");
    • 另外, 你不应该习惯使用/推荐在 if (isset($_POST["shubmit"])) 您的初始代码。
    • 新来者不会发现这样的拼写错误。它只是剥夺了你的 Php 通知, 这些非常情况下。添加 @isset验证功能后。
    • 首先修复原因。不是通知

  • @主要是可接受 $_GET 的/ $_POST 输入参数, 特别是如果它们是可选的

由于这涵盖了大多数此类问题, 让我们扩展到最常见的原因:

$_GET/ $_POST / $_REQUEST 未定义的输入

  • 遇到未定义的索引/偏移量时, 首先要做的是检查拼写错误:
    $count = $_GET["whatnow?"];

    • 这是预期的密钥名称, 并存在于每个页面请求上吗?
    • 变量名称数组征印数在 php 中区分大小写。
  • 其次, 如果通知没有明显的原因, 请使用 var_dumpprint_r 验证所有输入数组的当前内容:

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

    两者都将显示您的脚本是否被正确或任何参数调用。

  • 替代或额外使用浏览器 devtools ( F12 ) , 并检查网络选项卡的请求和参数:

    browser developer tools / network tab

    开机自检参数和 GET 输入将单独显示。

  • 对于 $_GET 参数, 您还 QUERY_STRING 可以查看

    print_r($_SERVER);
    

    PHP 有一些规则将非标准参数名称合并到超全局中。阿帕奇也可以做一些重写。 您还可以这样查看提供的原始 $_COOKIES 请求标头和其他 http 请求标头。

  • 更明显地查看您的浏览器地址栏的 get 参数:

    http://example.org/script.php?id=5&sort=desc

    name=value问号后的对 ? 是查询 (get) 参数。因此, 这个 URL 只能产生 $_GET["id"]$

第4个答案

通常是因为 "糟糕的编程", 现在或以后出现错误的可能性。

  1. 如果是错误, 请先对变量进行适当的分配: $varname = 0; 如果是错误, 则对变量进行正确的分配。
  2. 如果它真的只是有时只定义, 测试它: if (isset($varname)) , 在使用它之前
  3. 如果是因为你拼错了, 那就纠正一下
  4. 甚至可能在您的 php 设置中转向警告
第5个答案

这意味着您正在测试、评估或打印尚未分配任何内容的变量。 这意味着您要么有拼写错误, 要么需要先检查变量是否已初始化为某个内容。 检查逻辑路径, 它可以设置在一个路径中, 但不能设置在另一个路径中。

第6个答案

我不想禁用通知, 因为它很有帮助, 但想避免过多的打字。

我的解决方案是这个函数:

function ifexists($varname)
{
  return(isset($$varname)?$varname:null);
}

因此, 如果我想引用 $name 和回声 (如果存在), 我只需编写:

对于数组元素:

function ifexistsidx($var,$index)
{
  return(isset($var[$index])?$var[$index]:null);
}

在页面, 如果我想引用 $_ QUQUEST [' 名称 ']:

第7个答案

获取输入字符串的最佳方法是:

$value = filter_input(INPUT_POST, 'value');

此单行线几乎相当于:

if (!isset($_POST['value'])) {
    $value = null;
} elseif (is_array($_POST['value'])) {
    $value = false;
} else {
    $value = $_POST['value'];
}

如果您绝对想要字符串值, 就像:

$value = (string)filter_input(INPUT_POST, 'value');
第8个答案

这是因为变量 "$user _ 位置" 未被定义。如果您使用的是任何 if 循环, 其中您声明的是 "$user _ 位置" 变量, 那么您还必须有一个 else 循环并定义相同的循环。例如:

$a=10;
if($a==5) { $user_location='Paris';} else { }
echo $user_location;

上述代码将创建错误, 因为 if 循环不满足, 并且在其他循环 "$user _ 位置" 中未定义。PHP 仍然被要求回显该变量。因此, 要修改代码, 必须执行以下操作:

$a=10;
if($a==5) { $user_location='Paris';} else { $user_location='SOMETHING OR BLANK'; }
echo $user_location;
第9个答案

在回答 "为什么突然出现?我曾经使用这个脚本多年, 我从来没有遇到过任何问题.

大多数网站在 "显示所有错误, 但不显示" 通知 "和" 已弃用 "" 的 "默认" 错误报告下运行是非常常见的。这将在 php. ini 中设置, 并应用于服务器上的所有站点。这意味着示例中使用的 "通知" 将被抑制 (隐藏), 而其他被认为更关键的错误将被显示出来。

另一个关键设置是可以隐藏错误 (即 display_errors 设置为 "关闭" 或 "系统日志")。

在这种情况下, 会发生的情况是, 要么 error_reporting 已更改为也显示通知 (根据示例) 和/或设置已更改为在 display_errors 屏幕上 (而不是抑制主题/日志记录)。

他们为什么要改变?

最简单的答案是, 有人在 php. ini 中调整了这些设置中的任何一个, 或者 PHP 的升级版本现在使用的是与以前不同的 php. ini。那是第一个看的地方。

但是, 也可以在

  • . htconf (网络服务器配置, 包括 vhosts 和子配置) *
  • . htaccess
  • 在 php 代码本身

而这些也可能被改变。

还有一个额外的复杂, web 服务器配置可以启用/. htaccess 指令, 所以如果你有指令在. htaccess, 突然启动/停止工作, 那么你需要检查。

(. htconf/. htaccess 假设您是以 apache 的身份运行的。如果运行命令行, 这将不适用; 如果运行命令行, 则不适用。如果运行 IIS 或其他 web 服务器, 则需要相应地检查这些配置)

总结

  • error_reporting display_errors Php. ini 中的检查和 php 指令没有更改, 或者您没有使用与以前不同的 php. ini。
  • error_reporting display_errors 在. htconf (或 vhosts 等) 中的检查和 php 指令没有更改
  • error_reporting display_errors 在. htaccess 中的检查和 php 指令未更改
  • 如果您在. htaccess 中有指令, 请检查. htconf 文件中是否仍然允许它们
  • 最后检查您的代码;可能是一个不相关的图书馆;看看 error_reporting 是否 display_errors 在那里设置了 php 指令。
第10个答案

快速解决方法是将您的变量分配到代码顶部的 null

$user_location = null;
第11个答案

我曾经诅咒这个错误, 但它可以帮助提醒你逃避用户输入。

例如, 如果您认为这是聪明的速记代码:

// Echo whatever the hell this is

...再想想!更好的解决方案是:

// If this is set, echo a filtered version

(我使用自定义 html() 功能来逃避字符, 您的里程可能会有所不同)

第12个答案

我使用所有的时间自己的有用的函数exst () , 它自动声明变量。

您的代码将是-

$greeting = "Hello, ".exst($user_name, 'Visitor')." from ".exst($user_location);


/**
 * Function exst() - Checks if the variable has been set
 * (copy/paste it in any place of your code)
 *
 * If the variable is set and not empty returns the variable (no transformation)
 * If the variable is not set or empty, returns the $default value
 *
 * @param  mixed $var
 * @param  mixed $default
 *
 * @return mixed
 */

function exst( & $var, $default = "")
{
    $t = "";
    if ( !isset($var)  || !$var ) {
        if (isset($default) && $default != "") $t = $default;
    }
    else  {
        $t = $var;
    }
    if (is_string($t)) $t = trim($t);
    return $t;
}
第13个答案

用一种非常简单的语言。 错误的是, 您使用的变量 $user_location 不是由您以前定义的, 它没有任何值所以我建议您在使用此变量之前先声明它 , 例如:


$user_location = '';

$user_location = 'Los Angles';


这是一个非常常见的错误, 你可以面对。所以不用担心, 只需声明变量并享受编码.

第14个答案

在 PHP 7.0 中, 现在可以使用 Null 合并运算符:

echo "My index value is: " . ($my_array["my_index"] ?? '');

等于:

echo "My index value is: " . (isset($my_array["my_index"]) ? $my_array["my_index"] : '');

PHP 手动 PHP 7。0

第15个答案

为什么不保持简单呢?

第16个答案

为什么会发生这样的事?

随着时间的推移, PHP 已成为一种更加注重安全的语言。以前在默认情况下处于关闭状态的设置现在在默认情况下处于打开状态。这方面的一个很好的例子是 E_STRICT , 默认情况下, 5.4.0 php 时就打开了。

此外, 根据 PHP 文档, E_NOTICE 在 php. ini 中, defualt 禁用了。PHP 文档建议将其打开以进行调试。然而, 当我从 Ubuntu 存储库和 Bitnamami 的 Windows 堆栈下载 PHP 时, 我看到了其他的东西。

; Common Values:
;   E_ALL (Show all errors, warnings and notices including coding standards.)
;   E_ALL & ~E_NOTICE  (Show all errors, except for notices)
;   E_ALL & ~E_NOTICE & ~E_STRICT  (Show all errors, except for notices and coding standards warnings.)
;   E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR  (Show only errors)
; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
; http://php.net/error-reporting
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

请注意 error_reporting , 默认情况下实际设置为生产值, 而不是默认值设置为 "默认" 值。这有点令人困惑, 并且没有记录在 php. ini 之外, 所以我没有在其他发行版上验证这一点。

然而, 为了回答你的问题, 这个错误现在弹出, 当它以前没有弹出, 因为:

  1. 您安装了 PHP, 并且新的默认设置的文档有些不完整, 但不排除 E_NOTICE

  2. E_NOTICE未定义的变量和未定义的索引等警告实际上有助于使代码更干净、更安全。我可以告诉你, 多年前, 保持 E_NOTICE 启用迫使我声明我的变量。它使它更容易学习 C, 其中不声明变量是更大的麻烦。

我能做些什么呢?

  1. E_NOTICE通过复制 "默认值" 并 E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED 将其替换为在等号登录后当前未注释的内容来关闭 error_reporting = 。如果使用 CGI 或 FPM, 请重新启动 Apache 或 PHP。确保您正在编辑 "正确" 的 php. ini。正确的一个将是 Apache, 如果你正在运行 php 与 Apache, fpm 或 php-fpm, 如果运行 PHP-FPM, cgi, 如果运行 PHP-FPM 等。这不是推荐的方法, 但如果您有传统代码, 这将是极其难以编辑, 那么这可能是你最好的选择。

  2. 关闭 E_NOTICE 文件或文件夹级别。如果您有一些遗留代码, 但希望以 "正确" 的方式执行操作, 则这可能是比较可取的。要做到这一点, 你应该咨询 Apache2, nginx, 或任何你选择的服务器。在阿帕奇, 你会使用 php_value 里面 的。

  3. 重写代码以更干净。如果您在迁移到生产环境时需要执行此操作, 或者不希望他人看到您的错误, 请确保禁用任何错误显示, 并且只记录错误 (请参阅 display_errors log_errors php. ini 和服务器设置)。

扩大选项 3: 这是理想的选择。如果你能走这条路, 你就应该走。如果最初不走这条路, 请考虑最终通过在开发环境中测试代码来移动此路由。当你在做的时候, 摆脱 ~E_STRICT 它, ~E_DEPRECATED 看看未来可能会出现什么问题。你会看到很多不熟悉的错误, 但它会阻止你有一个

第17个答案

未定义的索引是指您为不可用的数组索引请求的数组中, 例如

未定义的变量是指您完全没有使用现有变量, 或者没有通过该名称定义或初始化该变量, 例如

未定义的偏移量表示您所要求的不存在的键的数组中。而解决这个问题的办法是在使用前检查

php> echo array_key_exists(1, $myarray);
第18个答案

关于问题的这一部分:

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

没有明确的答案, 但这里有一些可能的解释, 为什么设置可以 ' 突然 ' 改变:

  1. 您已将 PHP 升级到较新的版本, 该版本可能具有错误报告、显示错误或其他相关设置的其他默认值。

  2. 您已删除或引入了一些代码 (可能是在依赖项中), 这些代码在运行时使用 ini_set()error_reporting() (在代码中搜索这些设置)

  3. 您更改了 web 服务器配置 (假设此处为 apache): .htaccess 文件和 vhost 配置也可以操作 php 设置。

  4. 通常通知不会显示/报告 (请参阅php 手册), 因此在设置服务器时, 由于某种原因 (文件权限??), 可能无法加载 php. ini 文件, 并且您使用的是默认设置。稍后, "bug" 已被 (意外) 解决, 现在它可以加载正确的 php. ini 文件, 并设置错误 _ 报告以显示通知。

第19个答案

如果使用类, 则需要确保使用以下方法引用成员变量: $this

class Person
{
    protected $firstName;
    protected $lastName;

    public function setFullName($first, $last)
    {
        // Correct
        $this->firstName = $first;

        // Incorrect
        $lastName = $last;

        // Incorrect
        $this->$lastName = $last;
    }
}
第20个答案

引发未定义索引通知的另一个原因是数据库查询中省略了一列。

即。:

$query = "SELECT col1 FROM table WHERE col_x = ?";

然后尝试访问循环中的更多列。

即。:

print_r($row['col1']);
print_r($row['col2']); // undefined index thrown

或在 while 循环中:

while( $row = fetching_function($query) ) {

    echo $row['col1'];
    echo "";
    echo $row['col2']; // undefined index thrown
    echo "";
    echo $row['col3']; // undefined index thrown

}

需要注意的是, 在 * NIX OS 和 Mac OS X 上, 区分大小写的情况。

请咨询堆栈上的问答:

第21个答案

使用三元是简单、可读和干净的:

_Pre_PHP 7
如果设置了另一个变量的值, 则将其分配给另一个变量 null 的值, 否则将分配 (或所需的任何默认值):

$newVariable = isset($thePotentialData) ? $thePotentialData : null;

PHP 7 +
同样的, 除了使用空聚结算子。不再需要调用, isset() 因为这是内置的, 也不需要提供要返回的变量, 因为假定它返回要检查的变量的值:

$newVariable = $thePotentialData ?? null;

两者都将从 op 问题中停止通知,两者都与以下完全等效:

if (isset($thePotentialData)) {
    $newVariable = $thePotentialData;
} else {
    $newVariable = null;
}

如果不需要设置新变量, 则可以直接使用三元的返回值, 例如, echo 函数参数等:

回波:

echo 'Your name is: ' . isset($name) ? $name : 'You did not provide one';

功能:

$foreName = getForeName(isset($userId) ? $userId : null);

function getForeName($userId)
{
    if ($userId === null) {
        // Etc
    }
}

上面的工作将同样与数组, 包括会话等, 替换正在检查的变量, 例如:
$_SESSION['checkMe']
或您需要的深度的多个级别, 例如:
$clients['personal']['address']['postcode']


抑制:

可以使用 @ 错误报告级别来禁止显示 PHP 通知或减少错误报告级别, 但它不能解决问题, 它只是停止在错误日志中报告该通知。这意味着您的代码仍然尝试使用未设置的变量, 这可能意味着也可能不意味着某些内容无法正常工作--这取决于缺失值的重要性。

您确实应该检查此问题并适当地处理它, 或者为不同的消息提供服务, 甚至只是为其他所有内容返回一个空值, 以标识精确状态。

如果您只关心通知不在错误日志中, 那么作为一个选项, 您可以简单地忽略错误日志。

第22个答案

也许你一直在使用旧的 PHP 版本, 直到现在升级 PHP, 这就是为什么它的工作没有任何错误, 直到现在从几年。 直到 PHP4 没有错误, 如果你使用变量, 而不定义它, 但从 PHP5 起, 它抛出错误的代码, 如提到的问题。

第23个答案

在处理文件时, 需要适当的 enctype 和 POST 方法, 如果窗体中不包括其中一个, 则会触发未定义的索引通知。

该手册规定了以下基本语法:

Html






    Send this file:


Php

';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
    echo "File is valid, and was successfully uploaded.\n";
} else {
    echo "Possible file upload attack!\n";
}

echo 'Here is some more debugging info:';
print_r($_FILES);

print "";

第24个答案

提交 HTML 表单后不存在的变量的一个常见原因是窗体元素不包含

在标记中:

示例: 元素不包含在









    choice 1
    choice 2
    choice 3
    choice 4

示例: 元素现在包含在



        choice 1
        choice 2
        choice 3
        choice 4






第25个答案

我问了一个关于这个问题, 我被提到这个帖子与消息:

这个问题在这里已经有了答案:

"注意: 未定义的变量"、"注意: 未定义的索引" 和 "注意: 未定义的偏移量" 使用 PHP

我在这里分享我的问题和解决方案:

这是错误:

enter image description here

第 154 号线才是问题所在这就是我在第 154 部分中的内容:

153    foreach($cities as $key => $city){
154        if(($city != 'London') && ($city != 'Madrid') && ($citiesCounterArray[$key] >= 1)){

我认为问题是, 如果变量的条件, 这 $city 不是关键, 但在值, 我写的 $key => $city 是。首先, 你能确认这是不是警告的原因吗?其次, 如果这就是问题, 为什么我不能根据值写一个条件呢?写条件时, 我需要的是钥匙吗?

更新 1: 问题是, 在执行时 $citiesCounterArray[$key] , 有时 $key 对应于数组中不存在的键 $citiesCounterArray , 但根据我的循环的数据, 情况并不总是如此。我需要的是设置一个条件, 以便如果 $key 数组中存在, 则运行代码, 否则, 跳过它。

更新 2: 这是我如何使用 array_key_exists() 以下方法修复它:

foreach($cities as $key => $city){
    if(array_key_exists($key, $citiesCounterArray)){
        if(($city != 'London') && ($city != 'Madrid') && ($citiesCounterArray[$key] >= 1)){
第26个答案

这些通知是因为您没有使用的变量 defined , my_index 并且键没有出现到 $my_array 变量中。

这些通知每次都是触发的, 因为你不 code 正确, 但可能你没有报告通知。

解决这些错误:

$my_variable_name = "Variable name"; // defining variable
echo "My variable value is: " . $my_variable_name;

if(isset($my_array["my_index"])){
    echo "My index value is: " . $my_array["my_index"]; // check if my_index is set
}

另一种方法是把它拿出来:

ini_set("error_reporting", false)
第27个答案

在 PHP 中, 您需要先定义变量之后, 您可以使用它。
我们可以检查变量是定义或不是在非常有效的方式!

//If you only want to check variable has value and value has true and false value.
//But variable must be defined first.

if($my_variable_name){

}

//If you want to check variable is define or undefine
//Isset() does not check that variable has true or false value
//But it check null value of variable
if(isset($my_variable_name)){

}

简单的说明

//It will work with :- true,false,NULL
$defineVarialbe = false;
if($defineVarialbe){
    echo "true";
}else{
    echo "false";
}

//It will check variable is define or not and variable has null value.
if(isset($unDefineVarialbe)){
    echo "true";
}else{
    echo "false";
}

相关问题

mysql _ 拿给数组 ()/mysql_fetch_assoc ()/mysql_fetch_row ()/mysql_num_rows 等希望参数1是资源或结果 参考-此错误在 PHP 中意味着什么? 如何在 PHP 中分析和处理 HTML\ xml? "注意: 未定义的变量"、"注意: 未定义的索引" 和 "注意: 未定义的偏移量" 使用 PHP 删除数字数组中的所有重复数字 [重复] 使用数组中的键获取最小值 在循环中增加范围的上限并不能使它永远运行 [复制] 为什么我不需要使用 range () 在 for 循环中定义变量,但是我必须在 Python 中使用 while 循环? 为什么我总是启用编译器警告?