我正在运行一个PHP脚本,并继续收到错误,如:
注意:未定义变量my_variable_name在C:\wamp\www\mypath\index.php第10行
注意:第11行未定义索引:my_index C:\wamp\www\mypath\index.php
警告:在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"];
这些错误消息的含义是什么?
为什么他们会突然出现?我曾经使用这个脚本多年,从来没有任何问题。
我该如何修复它们?
这是一个一般参考问题,供人们链接作为副本,而不是需要一遍又一遍地解释这个问题。我觉得这很有必要,因为现实世界中关于这个问题的答案都非常具体。
相关元讨论:
如何应对重复的问题?
“参考问题”有意义吗?
错误显示@操作符
对于不需要的和多余的通知,可以使用专用的@操作符来»隐藏«未定义的变量/索引消息。
$var = @($_GET["optional_param"]);
这通常是不鼓励的。新人往往会过度使用它。
对于应用程序逻辑深处的代码(忽略不应该声明的未声明变量)是非常不合适的,例如函数参数或循环中。
isset有一个好处?:或??然而super-supression。通知仍然可以被记录。可以使用set_error_handler("var_dump")来恢复@-hidden通知;
另外,你不应该在初始代码中习惯性地使用/recommend if (isset($_POST["shubmit"]))。
新人不会发现这样的错别字。它只是剥夺了这些情况下的php注意。仅在验证功能后添加@或isset。
首先解决原因。不是通知。
@主要用于$_GET/$_POST输入参数,特别是在它们是可选的情况下。
既然这涵盖了大多数这样的问题,让我们扩展一下最常见的原因:
$_GET / $_POST / $_REQUEST未定义输入
当遇到未定义的索引/偏移量时,你要做的第一件事是检查错字:
$count = $_GET["whatnow?"];
这是每个页面请求中所期望的键名吗?
变量名和数组索引在PHP中是区分大小写的。
其次,如果通知没有明显的原因,使用var_dump或print_r来验证所有输入数组的当前内容:
var_dump ($ _GET);
var_dump ($ _POST);
/ / print_r ($ _REQUEST);
两者都将揭示您的脚本是否使用了正确的参数或任何参数调用。
或者使用你的浏览器devtools (F12)检查network选项卡中的请求和参数:
POST参数和GET输入将分别显示。
对于$_GET参数,还可以查看中的QUERY_STRING
_SERVER print_r ();
PHP有一些规则来将非标准参数名称合并到超全局参数中。Apache也可能会进行一些重写。
您还可以以这种方式查看提供的原始$_COOKIES和其他HTTP请求标头。
更明显的是查看浏览器地址栏的GET参数:
http://example.org/script.php?id=5&sort=desc
name=value在?问号是查询(GET)参数。因此,这个URL可能只会产生$_GET["id"]和$_GET["sort"]。
最后检查你的<form>和<input>声明,如果你期望一个参数但没有收到。
确保每个必需的输入都有一个<input name=FOO>
id=或title=属性是不够的。
method=POST表单应该填充$_POST。
而method=GET(或省略它)将产生$_GET变量。
表单也可以提供action=script.php?get=param通过$_GET和剩余的方法=POST字段在$_POST旁边。
对于现代PHP配置(≥5.6),再次使用$_REQUEST['vars']已经变得可行(不流行),它将GET和POST参数混在一起。
如果你正在使用mod_rewrite,那么你应该检查access.log以及启用RewriteLog来找出缺失的参数。
带有_file美元
同样的健全检查适用于文件上传和$_FILES["formname"]。
此外,检查enctype=multipart/form-data
以及<form>声明中的method=POST。
参见:PHP未定义索引错误$_FILES?
$ _COOKIE
$_COOKIE数组永远不会在setcookie()之后填充,而只在后续的HTTP请求中填充。
此外,它们的有效性会超时,它们可以被限制在子域或单个路径上,用户和浏览器可以拒绝或删除它们。
使用三元运算符简单、易读、干净:
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”)
或者取决于你需要多少层深度,例如:
美元的客户(“个人”)(“地址”)(“邮政编码”)
抑制:
可以用@屏蔽PHP通知或降低错误报告级别,但这并不能解决问题。它只是停止在错误日志中报告它。这意味着您的代码仍然试图使用一个未设置的变量,这可能意味着某些事情没有按照预期的方式工作——这取决于缺少的值有多重要。
您确实应该检查这个问题并适当地处理它,或者提供不同的消息,或者甚至只是为其他所有内容返回一个空值,以确定准确的状态。
如果您只关心通知不在错误日志中,那么可以选择忽略错误日志。