使用PHP的“注意:未定义的变量”,“注意:未定义的索引”和“注意:未定义的偏移量”


1173

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

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

注意:未定义的索引:第11行的my_index 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"];

这些错误消息是什么意思?

为什么它们突然出现?我曾经使用此脚本多年,但从未遇到任何问题。

我该如何解决?


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

相关元讨论:



3
该变量可能尚未初始化。您要从发布或获取或任何数组初始化变量吗?如果是这种情况,您可能在该数组中没有字段。那您的访问。
阿尼斯·席尔瓦

3
@Pekka웃-我注意到编辑中添加了“和“ Notice:Undefined offset””。-使用“ PHP:“ Undefined variable”,“ Undefined index”,“ Undefined offset”注意事项”(包括删除PHP,因为它被标记为“ php”。另外,URL被截断了and-notice-undef,只是一个建议,因此该URL不会被截断,甚至删除了(太多)引号,或者PHP: “Undefined variable/index/offset” notices
Funk Forty Niner

2
@Fred我想可以为这两种变化都提出一个论点。这样,新手就有机会在搜索查询中输入整行,包括“ Notice:”,我确定这是该问题的主要流量来源。如果消息完整,那么可能会提高搜索引擎的可见性
Pekka

2
@Pekka웃我明白。我之所以这么说是因为URL以前从未被切断,现在在and-notice-undef。这只是(几个)建议。它只是在重复自己Notice: Undefined
Funk 40 Niner

Answers:


1066

注意:未定义的变量

PHP手册的广泛智慧中:

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

PHP文档

如果变量不存在,则不会生成警告。这意味着 empty()本质上与!isset($ var)||等效是$ var ==假

这意味着,你可以只使用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不需要变量声明,但它确实推荐这样做,以避免某些安全漏洞或bug,因为这些漏洞或bug可能会忘记为变量提供值,该变量将在脚本的后面使用。在未声明变量的情况下,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'] ?? '';
  2. 为E_NOTICE 设置自定义错误处理程序,并将消息重定向到标准输出之外(也许重定向到日志文件):

    set_error_handler('myHandlerForMinorErrors', E_NOTICE | E_STRICT)
  3. 禁用E_NOTICE的报告功能。快速排除正义的方法E_NOTICE是:

    error_reporting( error_reporting() & ~E_NOTICE )
  4. 使用@运算符抑制错误。

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

使用或时$_POST,以上提示经常出现。对于,您只需要在使用索引之前检查索引是否存在。因为您必须确保您以会话开始,并且索引也存在。$_GET$_SESSION$_POST$_GET$_SESSIONsession_start()

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

有关:


7
@ dieselpower44一些想法:“关闭运算符”(@)存在一些性能问题。另外,由于它可以抑制特定范围内的所有错误,因此如果不加小心使用它,可能会掩盖您希望看到的消息。
IMSoP

6
隐藏问题不是解决问题的方法。项#2 ...#4只能在生产服务器上使用,通常不能使用。
Salman

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

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

@twistedpixel这4种方法是独立的,这不是4步指南。因此,如果您选择使用方式4,则意味着您尚未实现前3种方式,因此您尚未抑制任何错误。
AycanYaşıt2015年

141

试试这些

问题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);

关于会话的注意事项:


如果E_NOTICEphp.ini配置文件中使用,请执行error_reporting = (E_ALL & ~E_NOTICE)
ahmd0 2014年


从上面的答案中,我尝试过isset,array_key_exists,但是这些都不起作用。我尝试了您的答案.empty(),它有效。非常感谢你!
ewef

63

错误显示@运算符

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

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

    两者都将显示您的脚本是使用正确的权限还是任何参数调用的。

  • 另外,也可以使用浏览器devtoolsF12并检查“网络”标签中的请求和参数:

    浏览器开发人员工具/“网络”标签

    POST参数和GET输入将分别显示。

  • 对于$_GET参数,你还可以偷看了QUERY_STRING

    print_r($_SERVER);

    PHP有一些规则,以联合非标参数名称到超全局变量。Apache可能也会做一些重写。您也可以通过$_COOKIES这种方式查看提供的原始和其他HTTP请求标头。

  • 显然,请在浏览器地址栏中查看GET参数

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

    name=value后对?问号是你的查询(GET)的参数。因此,该网址只能产生$_GET["id"]$_GET["sort"]

  • 最后,如果需要参数但没有收到任何参数,请检查<form><input>声明。

    • 确保每个必需的输入都有一个 <input name=FOO>
    • id=title=属性是不够的。
    • 一个method=POST形式应该填充$_POST
    • method=GET(或忽略它)会产生$_GET变量。
    • 表单也可以action=script.php?get=param通过$ _GET和method=POST$ _POST中的其余字段一起提供。
    • 使用现代PHP配置(≥5.6 ),再次使用已变得可行(不流行)$_REQUEST['vars'],从而融合了GET和POST参数。
  • 如果您正在使用mod_rewrite,则应同时检查access.log和启用RewriteLog来找出缺少的参数。

$_FILES

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

$_COOKIE

  • $_COOKIE阵列是从来没有填充右后setcookie()在紧随,而只会在任何后续HTTP请求中。
  • 另外,它们的有效性会超时,它们可能会受到子域或单个路径的约束,并且用户和浏览器只能拒绝或删除它们。

2
如果您想知道对性能的影响是什么,这篇文章可以很好地总结一下,derickrethans.nl/…
Gajus 2014年

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

谢谢@mario,很有趣。现在,如果有人能很好地对这 两者进行基准测试... 3v4l.org/CYVOn/perf#tabs 3v4l.org/FLp3D/perf#tabs根据此测试,似乎是相同的(注意比例会发生变化)。
Gajus 2014年

47

通常是因为“编程错误”,以及现在或以后出现错误的可能性。

  1. 如果输入错误,请先为变量进行适当的赋值:$ varname = 0;
  2. 如果确实只是有时定义了它,请对其进行测试: if (isset($varname)),请在使用它之前进行
  3. 如果是因为您拼写错误,请更正
  4. 甚至在您的PHP设置中打开警告

5
请不要关闭警告。在更严格的语言中,它们通常表示“可能存在错误,您最好对这一行进行两次检查”-在像PHP这样宽容的语言中,它们通常意味着“此代码很烂,并且可能充斥着错误;我将尽力使有些感觉,但您最好尽快解决。”。

5
尽管我同意前三点,但#4完全是错误的。隐藏问题不会使其消失,甚至可能在将来引起更多问题。
Valentin Flachsel

1
@Freek绝对正确,但是在某些情况下(购买脚本,零技术知识,需要在明天开始运行...)这是胶带解决方案-确实很糟糕,始终需要强调,但可以选择
Pekka 2010年

胶带是好的...有时。从历史上讲,标准的PHP设置中都关闭了警告,但是默认设置变得更加严格。不幸的是,许多人会回到原来的设置,以免惹恼客户。
艾瑞克(Erik)2010年

41

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


34

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

我的解决方案是此功能:

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

因此,如果我要引用$ name并回显(如果存在),我只需写:

<?=ifexists('name')?>

对于数组元素:

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

在页面中,如果我要引用$ _REQUEST ['name']:

<?=ifexistsidx($_REQUEST,'name')?>

2
您的ifexists()函数在PHP 5.3中对我不起作用。调用方的变量在函数的本地范围内不可用(请参见Variable scope),除非它们是Superglobals或您在$ GLOBALS位置摆弄,所以$foo = "BABAR"; ifexists('foo');通常返回null。(斜体字是php.net的章节。)
skierpage 2012年

现在您会收到“你好”的提示。只需检查值if( !empty($user) and !empty($location) ) echo "hello $user ..."
gcb

27

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

$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');

25

这是因为未定义变量'$ user_location'。如果要在其中声明“ $ user_location”变量的情况下使用if循环,则还必须具有else循环并对其进行定义。例如:

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

上面的代码将创建错误,因为不满足if循环并且在else循环中未定义'$ user_location'。仍然要求PHP回显变量。因此,要修改代码,您必须执行以下操作:

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

25

回答“”,为什么它们突然出现?我曾经使用此脚本多年,而且从未遇到任何问题。”

对于大多数站点,在“显示所有错误,但不显示通知和弃用”的“默认”错误报告下运行是非常普遍的。这将在php.ini中设置,并应用于服务器上的所有站点。这意味着示例中使用的那些“通知”将被抑制(隐藏),而其他更重要的错误将被显示/记录。

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

在这种情况下将发生的情况是,要么error_reporting更改为还显示通知(根据示例),并且/或者将设置更改为display_errors在屏幕上显示(而不是禁止显示/记录它们)。

为什么要改变?

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

但是,也可以覆盖这些设置

  • .htconf(网络服务器配置,包括虚拟主机和子配置)*
  • .htaccess
  • 在PHP代码本身

并且其中任何一个也可能已更改。

Web服务器配置可以启用/禁用.htaccess指令还增加了复杂性,因此,如果.htaccess中的指令突然开始/停止工作,则需要进行检查。

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

摘要

  • 检查error_reportingdisplay_errorsphp.ini中的 php指令未更改,或者您没有使用与以前不同的php.ini。
  • .htconf(或虚拟主机等)中的Check error_reportingdisplay_errorsphp指令未更改
  • .htaccess中的Check error_reportingdisplay_errorsphp指令未更改
  • 如果您在.htaccess中有指令,请检查.htconf文件中是否仍然允许使用它们
  • 最后检查您的代码;可能是无关的库;查看是否已在此处设置error_reportingdisplay_errorsphp指令。


16

我曾经诅咒这个错误,但是提醒您避免用户输入可能会有所帮助。

例如,如果您认为这很聪明,则简写代码:

// Echo whatever the hell this is
<?=$_POST['something']?>

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

// If this is set, echo a filtered version
<?=isset($_POST['something']) ? html($_POST['something']) : ''?>

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


15

在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


这在if语句中也可以正常工作。 if (is_array($my_array['idontexist'] ?? '')) { dosomething(); }
编码员

您的代码实际上是一个很好的被忽略的错误:-仅检查isset(),如果您通过is_array()-是布尔值,则将发生意外行为。
elpiel

14

我一直使用自己有用的函数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;
}

14

用非常简单的语言
错误是您正在使用一个$user_location您之前未定义的变量,并且该变量没有任何值,因此,我建议您使用此变量之前先声明它,例如:


$user_location = '';
要么
$user_location = 'Los Angles';
这是您可能会遇到的非常常见的错误。因此,不必担心,只需声明变量并享受编码即可


8

为什么不保持简单?

<?php
error_reporting(E_ALL); // making sure all notices are on

function idxVal(&$var, $default = null) {
         return empty($var) ? $var = $default : $var;
  }

echo idxVal($arr['test']);         // returns null without any notice
echo idxVal($arr['hey ho'], 'yo'); // returns yo and assigns it to array index, nice

?>

8

为什么会这样?

随着时间的流逝,PHP已成为一种更加注重安全性的语言。以前默认情况下已关闭的设置现在默认情况下已打开。一个完美的例子是PHPE_STRICT,从PHP 5.4.0开始默认启用。

此外,根据PHP文档,默认情况下E_NOTICE在php.ini中是禁用的。PHP文档建议出于调试目的将其打开。但是,当我从Ubuntu存储库以及BitNami的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 =。重新启动Apache,如果使用CGI或FPM,则重新启动PHP。确保您正在编辑“正确的” php.ini。如果您将PHP与Apache一起运行,则正确的将是Apache,如果运行PHP-FPM,则将fpm或php-fpm,如果运行PHP-CGI,则将cgi,等等。这不是推荐的方法,但是如果您要使用旧代码,极难编辑,那可能是您最好的选择。

  2. 关闭E_NOTICE文件或文件夹级别。如果您有一些旧代码,但又想以“正确”的方式进行操作,则这可能是更可取的。为此,您应该查阅Apache2,Nginx或您选择的任何服务器。在Apache中,您可以php_value在中使用<Directory>

  3. 重写代码以使代码更整洁。如果您在移至生产环境时需要执行此操作,或者不想让别人看到您的错误,请确保禁用任何错误显示,并仅记录错误(请参见display_errorslog_errors在php.ini中以及您的服务器设置中) 。

要扩展选项3:这是理想的选择。如果您可以走这条路,那应该。如果您最初不打算走这条路线,请考虑通过在开发环境中测试代码来最终走这条路线。当你在它,摆脱~E_STRICT,并~E_DEPRECATED看看有什么可能出错的未来。您将看到很多不熟悉的错误,但是当您将来需要升级PHP时,它将阻止您遇到任何不愉快的问题。

错误是什么意思?

Undefined variable: my_variable_name-使用前未定义变量时,会发生这种情况。当执行PHP脚本时,它在内部仅假定为空值。但是,在哪种情况下您需要在定义变量之前检查变量?最终,这是“草率代码”的参数。作为开发人员,当我看到一个开源项目时,我可以告诉您我喜欢它。它使人们更容易判断将来将弹出哪些变量,并使阅读/学习代码更加容易。

function foo()
{
    $my_variable_name = '';

    //....

    if ($my_variable_name) {
        // perform some logic
    }
}

Undefined index: my_index-当您尝试访问数组中的值并且它不存在时,会发生这种情况。为避免此错误,请执行条件检查。

// verbose way - generally better
if (isset($my_array['my_index'])) {
    echo "My index value is: " . $my_array['my_index'];
}

// non-verbose ternary example - I use this sometimes for small rules.
$my_index_val = isset($my_array['my_index'])?$my_array['my_index']:'(undefined)';
echo "My index value is: " . $my_index_val;   

另一种选择是在函数顶部声明一个空数组。这并不总是可能的。

$my_array = array(
    'my_index' => ''
);

//...

$my_array['my_index'] = 'new string';

(其他提示)

  • 当我遇到这些问题和其他问题时,我使用了NetBeans IDE(免费),它给了我很多警告和注意。其中一些提供了非常有用的提示。这不是必需的,除了大型项目之外,我不再使用IDE。vim这些天我更像一个人:)。

6

未定义索引表示在您请求的数组中不可用的数组索引中,例如

<?php 

$newArray[] = {1,2,3,4,5};
print_r($newArray[5]);

?>

未定义的变量意味着您已经使用了完全不存在的变量,或者未使用该名称定义或初始化的变量

<?php print_r($myvar); ?>

未定义的偏移量表示您要求不存在的键在数组中。解决方案是使用前检查

php> echo array_key_exists(1, $myarray);

4

关于这部分问题:

为什么它们突然出现?我曾经使用此脚本多年,但从未遇到任何问题。

没有确切的答案,但是以下是一些设置可能会“突然”更改的可能解释:

  1. 您已将PHP升级到较新的版本,该版本可以具有error_reporting,display_errors或其他相关设置的其他默认值。

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

  3. 您更改了Web服务器配置(此处为apache):.htaccess文件和虚拟主机配置也可以操纵php设置。

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


3

如果使用类,则需要确保使用引用成员变量$this

class Person
{
    protected $firstName;
    protected $lastName;

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

        // Incorrect
        $lastName = $last;

        // Incorrect
        $this->$lastName = $last;
    }
}

3

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

即:

$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 "<br>";
    echo $row['col2']; // undefined index thrown
    echo "<br>";
    echo $row['col3']; // undefined index thrown

}

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

请参阅以下有关堆栈的问答:


3

使用三元是简单,易读且干净的:

PHP 7
分配给另一个变量的值的变量,如果它的设置,否则分配null(或任何默认值,你需要):

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

PHP 7+
除使用Null合并运算符外,其他均相同。isset()因为内置了它,所以不再需要调用,也不需要提供要返回的变量,因为它假定返回要检查的变量的值:

$newVariable = $thePotentialData ?? null;

两者都将停止来自OP问题的通知,并且两者完全等同于:

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

 
如果您不需要设置新变量,则可以直接使用三元组的返回值,例如with echo,function arguments等:

回声:

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声明@或降低错误报告级别,但是不能解决问题,它只是停止在错误日志中报告该问题。这意味着您的代码仍尝试使用未设置的变量,这可能意味着某项未按预期工作,这取决于缺失值的重要性。

您确实应该检查此问题并进行适当处理,或者发送不同的消息,甚至为其他所有内容返回空值以标识准确的状态。

如果您只是在乎通知不在错误日志中,那么可以选择忽略错误日志。


1

提交HTML表单后,变量不存在的常见原因是<form>标记中未包含form元素:

示例:元素不包含在 <form>

<form action="example.php" method="post">
    <p>
        <input type="text" name="name" />
        <input type="submit" value="Submit" />
    </p>
</form>

<select name="choice">
    <option value="choice1">choice 1</option>
    <option value="choice2">choice 2</option>
    <option value="choice3">choice 3</option>
    <option value="choice4">choice 4</option>
</select>

示例:元素现在包含在 <form>

<form action="example.php" method="post">
    <select name="choice">
        <option value="choice1">choice 1</option>
        <option value="choice2">choice 2</option>
        <option value="choice3">choice 3</option>
        <option value="choice4">choice 4</option>
    </select>
    <p>
        <input type="text" name="name" />
        <input type="submit" value="Submit" />
    </p>
</form>

0

直到现在您可能一直在使用旧版本的PHP,现在又升级了PHP,这就是多年来它一直没有任何错误的原因。直到PHP4为止,如果您使用的是未定义变量就没有错误,但是从PHP5开始,它会为上述代码引发错误。


0

处理文件时,需要适当的enctype和POST方法,如果表单中未包含任何两者,则它们将触发未定义的索引通知。

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

的HTML

<!-- The data encoding type, enctype, MUST be specified as below -->
<form enctype="multipart/form-data" action="__URL__" method="POST">
    <!-- MAX_FILE_SIZE must precede the file input field -->
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    <!-- Name of input element determines name in $_FILES array -->
    Send this file: <input name="userfile" type="file" />
    <input type="submit" value="Send File" />
</form>

的PHP

<?php
// In PHP versions earlier than 4.1.0, $HTTP_POST_FILES should be used instead
// of $_FILES.

$uploaddir = '/var/www/uploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

echo '<pre>';
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 "</pre>";

?>

参考:


0

我问了一个有关此的问题,并在此消息中提到了我:

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

使用PHP的“注意:未定义变量”,“注意:未定义索引”和“注意:未定义偏移量”

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

这是错误:

在此处输入图片说明

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)){

0

每当我们使用未设置的变量时,就会发生这些错误。

处理这些问题的最佳方法是在开发过程中设置错误报告。

设置错误报告的依据:

ini_set('error_reporting', 'on');
ini_set('display_errors', 'on');
error_reporting(E_ALL);

在生产服务器上,错误报告处于关闭状态,因此,我们不会收到这些错误。

但是,在开发服务器上,我们可以设置错误报告。

为了摆脱这个错误,我们看下面的例子:

if ($my == 9) {
 $test = 'yes';  // Will produce error as $my is not 9.
}
echo $test;

我们可以NULL在分配变量值或使用变量之前将其初始化为。

因此,我们可以将代码修改为:

$test = NULL;
if ($my == 9) {
 $test = 'yes';  // Will produce error as $my is not 9.
}
echo $test;

即使$test没有值,也不会打扰任何程序逻辑,也不会产生通知。

因此,基本上,将错误报告设置为开发总是更好。

并修复所有错误。

在生产中,错误报告应设置为关闭。


-1

这些通知是因为您没有使用过的变量,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)

-2

在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";
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.