我正在运行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"];
这些错误消息的含义是什么?
他们为什么突然出现?我曾经使用这个脚本多年,我从来没有遇到任何问题 .
我该如何解决?
这是一个一般参考问题,供人们链接到重复,而不是一遍又一遍地解释问题 . 我觉得这是必要的,因为关于这个问题的大多数现实世界的答案都非常具体 . 相关元讨论:重复性问题可以做些什么? “参考问题”有意义吗?
27 回答
注意:未定义的变量
来自PHP Manual的广阔智慧:
来自PHP documentation:
这意味着您只能使用
empty()
来确定是否设置了变量,此外它还会根据以下内容检查变量0,"",null
.例:
测试3v4l.org online PHP editor中的上述代码片段
尽管PHP不需要变量声明,但它确实建议使用它以避免一些安全漏洞或错误,因为人们会忘记为稍后将在脚本中使用的变量赋值 . PHP在未声明变量的情况下所做的是发出一个非常低级别的错误,
E_NOTICE
,默认情况下甚至没有报告,但在开发期间是手动advises to allow .处理问题的方法:
从PHP 7.0开始,这变得更加清晰,现在你可以使用null coalesce operator:
E_NOTICE
的快速方法是:Note: 强烈建议仅实施第1点 .
注意:未定义的索引/未定义的偏移量
当您(或PHP)尝试访问数组的未定义索引时,会出现此通知 .
处理问题的方法:
两个变量用于访问两个数组元素,但是只有一个数组元素index
0
,所以这将生成:$ _POST / $ _GET / $ _SESSION变量
使用
$_POST
,$_GET
或$_SESSION
时,通常会出现上述注意事项 . 对于$_POST
和$_GET
,您只需在使用之前检查索引是否存在 . 对于$_SESSION
,您必须确保以session_start()开始会话并且索引也存在 .另请注意,所有3个变量都是superglobals并且是大写的 .
有关:
Notice: Undefined variable
Notice: Undefined Index
试试这些
或者,作为快速而肮脏的解决方案:
关于会话的说明:
使用会话时,需要将
session_start();
放在所有使用的文件中会话 .http://php.net/manual/en/features.sessions.php
错误显示@运算符
对于不需要的和冗余的通知,可以使用专用的@ operator到» hide «未定义的变量/索引消息 .
通常不鼓励这样做 . 新移民倾向于过度使用它 .
It 's very inappropriate for code deep within the application logic (ignoring undeclared variables where you shouldn' t),例如用于函数参数或循环 .
然而,
isset?:
或??
超级抑制有一个好处 . 通知仍然可以记录 . 并且可以通过以下方式恢复@
隐藏的通知:set_error_handler("var_dump");
另外,您不应该习惯性地在初始代码中使用/推荐
if (isset($_POST["shubmit"]))
.新人不会发现这样的错别字 . 它只是剥夺了PHP的注意事项 . 仅在验证功能后添加
@
或isset
.@主要适用于
$_GET
/$_POST
输入参数,特别是如果它们是可选的 .由于这涵盖了大多数此类问题,让我们扩展最常见的原因:
$ _GET / $ _POST / $ _REQUEST未定义的输入
遇到未定义的索引/偏移量时,首先要做的是检查拼写错误:
$count = $_GET["whatnow?"];
这是一个预期的密钥名称并出现在每个页面请求中吗?
变量名称 and 数组指示在PHP中区分大小写 .
其次,如果通知没有明显原因,请使用var_dump或print_r验证 all 输入数组的内容:
两者都将揭示您的脚本是否使用正确或任何参数调用 .
POST参数和GET输入将单独显示 .
$_GET
参数,您还可以查看QUERY_STRING inPHP有一些规则将coalesce非标准参数名称放入superglobals中 . Apache也可能会进行一些重写 . 您还可以通过这种方式查看提供的原始
$_COOKIES
和其他HTTP请求标头 .http://example.org/script.php?id=5&sort=desc
?
问号之后的name=value
对是您的查询(GET)参数 . 因此,此URL只能产生$_GET["id"]
和$_GET["sort"]
.如果您希望参数但未接收任何参数,请最后检查您的 <form> and <input> 声明 .
确保每个必需的输入都有
<input name=FOO>
id=
或title=
属性不够 .method=POST
表格应该填充$_POST
.而
method=GET
(或将其遗漏)将产生$_GET
变量 .表单也可以通过$ _GET和$ _POST中的剩余
method=POST
字段提供action=script.php?get=param
.使用现代PHP配置(≥5.6)再次使用$_REQUEST['vars']已成为feasible(非时尚),它会使GET和POST参数混淆 .
如果您正在使用mod_rewrite,那么您应该检查
access.log
以及启用RewriteLog以找出缺少的参数 .$ _FILES
相同的健全性检查适用于文件上传和
$_FILES["formname"]
.此外检查
enctype=multipart/form-data
以及
<form>
声明中的method=POST
.参见:PHP Undefined index error $_FILES?
$ _COOKIE
$_COOKIE
数组永远不会在setcookie()
之后填充,但仅限于任何后续HTTP请求 .此外,它们的有效性超时,它们可能是对子域或单个路径的约束,用户和浏览器可以拒绝或删除它们 .
一般是因为“糟糕的编程”,现在或以后都有可能出错 .
如果这是一个错误,请首先对变量进行适当的赋值:$ varname = 0;
如果它确实只是有时定义,请在使用之前测试它:
if (isset($varname))
如果是因为拼错了,那就纠正错误吧
甚至可能会转动你的警告 PHP-settings
这意味着您正在测试,评估或打印尚未分配任何内容的变量 . 这意味着您要么输入错误,要么需要先检查变量是否已初始化为某些内容 . 检查您的逻辑路径,它可以设置在一个路径中,但不能设置在另一个路径中 .
我不想禁用通知,因为它有用,但是想避免太多打字 .
我的解决方案是这样功能:
所以,如果我想引用$ name和echo if exists,我只需写:
对于数组元素:
在页面中如果我想引用$ _REQUEST ['name']:
获取输入 string 的最佳方法是:
这个单线几乎相当于:
如果你绝对想要 string 值,就像:
这是因为没有定义变量'$ user_location' . 如果您正在使用任何if循环来声明'$ user_location'变量,那么您还必须有一个else循环并定义相同的循环 . 例如:
上面的代码将创建错误,因为if循环不满足,并且在else循环中'$ user_location'未定义 . 仍然要求PHP回应变量 . 因此,要修改代码,您必须执行以下操作:
In reply to ""Why do they appear all of a sudden? I used to use this script for years and I've never had any problem."
大多数网站在“显示所有错误,但不是'通知'和'已弃用'”的“默认”错误报告下运行是很常见的 . 这将在php.ini中设置并应用于服务器上的所有站点 . 这意味着示例中使用的那些“通知”将被抑制(隐藏),而其他错误(被认为更为关键)将被显示/记录 .
另一个关键设置是可以隐藏错误(即
display_errors
设置为"off"或"syslog") .在这种情况下会发生的事情是
error_reporting
被更改为还显示通知(根据示例)和/或设置在屏幕上更改为display_errors
(而不是禁止/记录它们) .Why have they changed?
显而易见/最简单的答案是,有人在php.ini中调整了这些设置中的任何一个,或者PHP的升级版现在使用了之前不同的php.ini . 这是第一个看的地方 .
但是,也可以覆盖这些设置
.htconf(网络服务器配置,包括虚拟主机和子配置)*
.htaccess
在PHP代码本身
其中任何一个也可以改变 .
还有一个额外的复杂性,即Web服务器配置可以启用/禁用.htaccess指令,因此如果.htaccess中的指令突然启动/停止工作,那么您需要检查它 .
(.htconf / .htaccess假设您正在以apache身份运行 . 如果运行命令行,则不适用;如果运行IIS或其他Web服务器,则需要相应地检查这些配置)
Summary
检查php.ini中的
error_reporting
和display_errors
php指令没有改变,或者你之前没有使用不同的php.ini .检查.htconf(或vhosts等)中的
error_reporting
和display_errors
php指令没有改变检查.htaccess中的
error_reporting
和display_errors
php指令没有改变如果.htaccess中有指令,请检查.htconf文件中是否仍允许它们
最后检查你的代码;可能是一个无关的图书馆;看看是否已经设置了
error_reporting
和display_errors
php指令 .快速解决方法是在代码顶部将变量赋值为null
我曾经诅咒这个错误,但提醒你逃避用户输入会很有帮助 .
例如,如果您认为这是一个聪明的速记代码:
...再想想!更好的解决方案是:
(我使用自定义
html()
函数来逃避角色,你的里程可能会有所不同)我一直使用自己有用的函数 exst() ,它自动声明变量 .
你的代码将是 -
在一个非常 Simple Language .
错误是你使用的变量
$user_location
不是你之前定义的,它没有任何值所以我建议你请 declare 这个变量 before using 它,例如:$user_location = '';
Or
$user_location = 'Los Angles';
这是一个非常常见的错误 . 所以不要担心只是声明变量和 Enjoy Coding .
在PHP 7.0中,现在可以使用Null合并运算符:
等于:
PHP manual PHP 7.0
为什么不把事情简单化?
为什么会发生这种情况?
随着时间的推移,PHP已成为一种更加注重安全性的语言 . 默认情况下,以前关闭的设置现在处于打开状态 . 一个完美的例子是
E_STRICT
,默认情况下从PHP 5.4.0开启 .此外,根据PHP文档,通过defualt,在php.ini中禁用
E_NOTICE
. PHP文档推荐turning it on for debugging purposes . 但是,当我从Ubuntu存储库下载PHP并从BitNami的Windows堆栈中下载时,我看到了别的东西 .请注意,
error_reporting
实际上默认设置为 生产环境 值,而不是默认设置为"default"值 . 这有点令人困惑,并没有在php.ini之外记录,所以我在其他发行版上验证了这一点 not .但是,要回答您的问题,此错误会在之前未弹出时弹出,原因是:
您安装了PHP并且新的默认设置文档记录较差,但不排除
E_NOTICE
.E_NOTICE
警告,如未定义的变量和未定义的索引实际上有助于使您的代码更清洁,更安全 . 我可以告诉你,多年前,保持启用E_NOTICE
强迫我声明我的变量 . 它使得学习C更容易,其中没有声明变量是一个更大的麻烦 .我可以做些什么?
通过复制"Default value"
E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
关闭E_NOTICE
并将其替换为error_reporting =
中等号后当前取消注释的内容 . 如果使用CGI或FPM,请重新启动Apache或PHP . 确保您正在编辑"right" php.ini . 正确的一个是Apache,如果你运行PHP的Apache,fpm或php-fpm,如果运行PHP-FPM,cgi,如果运行PHP-CGI,等等 . 这不是推荐的方法,但如果你有遗留代码,那将是非常难以编辑,那么它可能是你最好的选择 .在文件或文件夹级别关闭
E_NOTICE
. 如果您有一些遗留代码但希望以"right"方式执行操作,这可能更为可取 . 为此,您应该咨询Apache2,nginx或您选择的服务器 . 在Apache中,您将在<Directory>
中使用php_value
.重写您的代码以使其更清洁 . 如果您在迁移到 生产环境 环境时需要执行此操作,或者不希望有人看到您的错误,请确保您禁用任何错误显示,并且只有 logging 您的错误(请参阅php.ini中的
display_errors
和log_errors
以及您的错误服务器设置) .扩展选项3:这是理想的选择 . 如果你能走这条路,你应该 . 如果您最初没有使用此路由,请考虑最终通过在开发环境中测试代码来移动此路由 . 当你在它的时候,摆脱
~E_STRICT
和~E_DEPRECATED
看看将来会出现什么问题 . 当你将来需要升级PHP时,你会阻止你有任何不愉快的问题 .错误意味着什么?
Undefined variable: my_variable_name
- 在使用前未定义变量时会发生这种情况 . 执行PHP脚本时,它在内部只假定一个空值 . 但是,在哪种情况下,您需要在定义变量之前检查变量?最终,这是"sloppy code"的论据 . 作为开发人员,我可以告诉你,当我看到一个开源项目时,我喜欢它,在这个项目中,变量被定义为可以定义的范围内的高位 . 它可以更容易地告诉将来会弹出哪些变量,并且更容易阅读/学习代码 .Undefined index: my_index
- 当您尝试访问数组中的值并且它不存在时,会发生这种情况 . 要防止此错误,请执行条件检查 .另一种选择是在函数顶部声明一个空数组 . 这并不总是可行的 .
(额外提示)
vim
人:) .例如,未定义的索引表示您为不可用的数组索引请求的数组
未定义的变量意味着您完全不使用现有变量,或者未使用该名称定义或初始化该变量
undefined offset表示您已请求不存在的键 . 解决方法是在使用前进行检查
关于这部分问题:
没有明确的答案,但这里有一些可能的解释为什么设置可以“突然”改变:
您已将PHP升级到较新版本,该版本可能具有error_reporting,display_errors或其他相关设置的其他默认值 .
您已删除或介绍了一些代码(可能在依赖项中),它们在运行时使用
ini_set()
或error_reporting()
设置相关设置(在代码中搜索这些)您更改了Web服务器配置(假设此处为apache):
.htaccess
文件和vhost配置也可以操作php设置 .通常没有显示/报告通知(参见PHP manual),因此在设置服务器时,由于某种原因(文件权限??)无法加载php.ini文件,并且您处于默认设置 . 后来,'bug'已经解决(偶然),现在它可以加载正确的php.ini文件,并设置error_reporting来显示通知 .
如果使用类,则需要确保使用
$this
引用成员变量:将抛出未定义的索引通知的另一个原因是,数据库查询中省略了一列 .
即:
然后尝试访问循环内的更多列/行 .
即:
或者在
while
循环中:需要注意的是,在* NIX OS和Mac OS X上,事情区分大小写 .
请参阅堆栈上的以下问答:
Are table names in MySQL case sensitive?
mysql case sensitive table names in queries
MySql - Case Sensitive issue of tables in different server
使用ternary简单,易读且干净:
Pre PHP 7
如果设置了另一个变量的值,则将变量分配给另一个变量的值,否则分配
null
(或者您需要的任何默认值):PHP 7+
除了使用Null Coalescing Operator之外 . 不再需要调用
isset()
,因为它是内置的,并且不需要提供变量来返回,因为它假定返回被检查变量的值:Both 将停止OP问题的通知, both 与以下内容完全相同:
如果你没有't require setting a new variable then you can directly use the ternary'的返回值,例如
echo
,函数参数等:Echo:
Function:
以上将与数组相同,包括会话等,用例如替换被检查的变量:
$_SESSION['checkMe']
或者你需要多深层次,例如:
$clients['personal']['address']['postcode']
Suppression:
可以使用
@
来抑制PHP通知或降低错误报告级别,但它只是停止在错误日志中报告它 . 这意味着您的代码仍然尝试使用未设置的变量,这可能会或可能不会意味着某些内容无法正常工作 - 具体取决于缺失值的重要性 .你应该真正检查这个问题并适当地处理它,或者提供不同的消息,或者甚至只是为其他一切返回一个空值来识别精确的状态 .
如果您只关心通知不在错误日志中,那么作为选项,您可以简单地忽略错误日志 .
可能你使用旧的PHP版本,直到现在升级PHP,这是它工作的原因,直到现在多年来没有任何错误 . 直到PHP4,如果您在没有定义变量的情况下使用变量,则没有错误,但从PHP5开始,它会抛出相关问题的错误 .
处理文件时,需要正确的enctype和POST方法,如果表单中没有包含任何索引,则会触发未定义的索引通知 .
手册说明了以下基本语法:
HTML
PHP
参考:
提交HTML表单后变量不存在的一个常见原因是表单元素未包含在
<form>
标记中:Example: Element not contained within the <form>
Example: Element now contained within the <form>
我问了一个关于这个的问题,我在这篇文章中提到了这样的信息:
我在这里分享我的问题和解决方案:
这是错误:
第154行是问题所在 . 这就是我在154行中的内容:
我认为问题是我正在编写变量
$city
的条件,这不是关键,而是$key => $city
中的值 . 首先,您能否确认这是否是警告的原因?第二,如果那是问题,为什么我不能根据 Value 写出条件呢?是否必须使用我需要写入条件的密钥?更新1:问题是当执行
$citiesCounterArray[$key]
时,有时$key
对应于a$citiesCounterArray
数组中不存在的键,但根据我的循环数据并非总是如此 . 我需要的是设置一个条件,以便如果数组中存在$key
,则运行代码,否则,跳过它 .更新2:这是我使用
array_key_exists()
修复它的方法:这些通知是因为您没有使用变量
defined
并且$my_array
变量中没有my_index
键 .这些通知每次都被触发,因为你的
code
不正确,但可能你没有报告通知 .解决错误:
解决这个问题的另一种方法:
在PHP中,您需要先定义变量,然后才能使用它 .
我们可以非常有效地检查变量是否定义!
Simple Explanation