“notice:undefined variable”、“notice:undefined index”和“notice:undefined offset”使用php

czq61nw1  于 2021-06-17  发布在  Mysql
关注(0)|答案(9)|浏览(354)

我正在运行一个php脚本,并继续收到如下错误:
注意:未定义变量:第10行的c:\wamp\www\mypath\index.php中的my\u variable\u name
注意:未定义索引:myu index c:\wamp\www\mypath\index.php,第11行
第10行和第11行是这样的:

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

这些错误消息是什么意思?
为什么它们突然出现?我用这个脚本好几年了,从来没有遇到过任何问题。
我该如何修复它们?
这是一个一般性的参考问题,人们可以将其作为重复链接,而不必反复解释这个问题。我觉得这是必要的,因为在这个问题上,大多数现实世界的答案都非常具体。
相关元讨论:
重复性问题怎么办?
“参考问题”有意义吗?

i1icjdpr

i1icjdpr1#

这是因为没有定义变量“$user\u location”。如果您使用的是任何if循环,其中声明了“$user\u location”变量,那么您还必须有一个else循环并定义相同的循环。例如:

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

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

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

3mpgtkmj2#

注意:变量未定义

从php手册的巨大智慧中:
如果将一个文件包含到另一个使用相同变量名的文件中,依赖未初始化变量的默认值是有问题的。打开register\u globals也是一个主要的安全风险。在处理未初始化的变量时会发出e\u通知级别的错误,但是在将元素附加到未初始化的数组时则不会。isset()语言构造可用于检测变量是否已初始化。此外,更理想的解决方案是empty(),因为如果变量未初始化,它不会生成警告或错误消息。
来自php文档:
如果变量不存在,则不会生成警告。这意味着empty()本质上是!isset($var)| |$var==false。
这意味着你只能使用 empty() 确定是否设置了变量,并根据以下内容检查变量:, 0 , 0.0 , "" , "0" , null , false 或者 [] .
例子:

$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 ,默认情况下甚至没有报告,但手册建议在开发过程中允许。
处理问题的方法:
建议:声明您的变量,例如当您尝试将字符串附加到未定义的变量时。或使用 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'] : '';

这在PHP7.0中变得更加清晰,现在可以使用null coalesce操作符:

// Null coalesce operator - No need to explicitly initialize the variable.
$value = $_POST['value'] ?? '';

为e\u notice设置一个自定义错误处理程序,并将消息从标准输出重定向到另一个日志文件:

set_error_handler('myHandlerForMinorErrors', E_NOTICE | E_STRICT)

禁止e\ U通知报告。一种快速排除 E_NOTICE 是:

error_reporting( error_reporting() & ~E_NOTICE )

使用@运算符抑制错误。
注意:强烈建议只实现第1点。

注意:未定义索引/未定义偏移

当您(或php)尝试访问数组的未定义索引时,会出现此通知。
处理问题的方法:
在访问之前,请检查索引是否存在。你可以用这个 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'] : '';

语言结构 list() 当它试图访问不存在的数组索引时,可能会生成以下内容:

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

两个变量用于访问两个数组元素,但是只有一个数组元素index 0 ,这将生成:
注意:未定义的偏移:1

$\u post/$\u get/$\u session变量

使用时,上面的注意事项经常出现 $_POST , $_GET 或者 $_SESSION . 为了 $_POST 以及 $_GET 在使用它们之前,您只需检查索引是否存在。为了 $_SESSION 你必须确保你的会话是从 session_start() 索引也存在。
还要注意的是,这3个变量都是超全局的,都是大写的。
相关:
注意:变量未定义
注意:未定义索引

hk8txs48

hk8txs483#

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

有关会话的说明:
使用会话时, session_start(); 需要放置在使用会话的所有文件中。
http://php.net/manual/en/features.sessions.php

yzckvree

yzckvree4#

错误显示@操作员

对于不需要的和多余的通知,可以使用专用的 @ 操作员到»隐藏« 未定义的变量/索引消息。

$var = @($_GET["optional_param"]);

这通常是不鼓励的。新来者往往会过度使用它。
对于应用程序逻辑的深层代码(忽略不应该声明的未声明变量),例如函数参数或循环中的代码,这是非常不合适的。
上面有一个 isset?: 或者 ?? 超级压制。通知仍然可以被记录。一个人可能会复活 @ -隐藏通知: set_error_handler("var_dump"); 另外,你不应该习惯性地使用/推荐 if (isset($_POST["shubmit"])) 在你的初始代码中。
初来乍到的人不会发现这样的拼写错误。它只是剥夺了你的phps通知那些非常的情况。添加 @ 或者 isset 仅在验证功能之后。
先解决原因。不是通知。 @ 主要适用于 $_GET / $_POST 输入参数,特别是如果它们是可选的。
既然这涵盖了大多数这样的问题,让我们来扩展一下最常见的原因:

$\u get/$\u post/$\u请求未定义的输入

遇到未定义的索引/偏移量时,首先要检查是否有打字错误: $count = $_GET["whatnow?"]; 这是一个预期的关键字名称,并出现在每个页面请求中吗?
在php中,变量名和数组指示符区分大小写。
其次,如果通知没有明显的原因,使用 var_dump 或者 print_r 要验证所有输入数组的当前内容,请执行以下操作:

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

两者都将显示是否使用正确的参数或任何参数调用了脚本。
或者另外使用浏览器开发工具(f12),检查“网络”选项卡中的请求和参数:

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)参数。因此,这个url只能产生 $_GET["id"] 以及 $_GET["sort"] .
最后检查你的 <form> 以及 <input> 声明,如果您需要一个参数,但没有收到任何参数。
确保每个必需的输入都有一个 <input name=FOO> 这个 id= 或者 title= 属性不足。
method=POST 表单应该填充 $_POST .
鉴于 method=GET (或不说)就会让步 $_GET 变量。
也可以提供一个表单 action=script.php?get=param 通过$获取和剩余的 method=POST $中的字段并排发布。
使用现代php配置(≥ 5.6)使用已变得可行(不时尚) $_REQUEST['vars'] 同样,mashes获取并发布参数。
如果您使用mod\u rewrite,那么您应该检查 access.log 以及启用 RewriteLog 找出缺少的参数。

$\u文件

同样的健全性检查也适用于文件上载和 $_FILES["formname"] .
此外,检查 enctype=multipart/form-data 以及 method=POST 在你的 <form> 宣言。
另请参阅:php未定义索引错误$\u文件?

$\饼干

这个 $_COOKIE 数组不会立即填充 setcookie() ,但仅适用于任何后续http请求。
此外,它们的有效性超时,它们可能被约束到子域或单个路径,用户和浏览器可以拒绝或删除它们。

cgvd09ve

cgvd09ve5#

一般是因为“编程不好”,现在或以后都有可能出错。
如果是错误的,请首先对变量进行正确的赋值:$varname=0;
如果它确实只是有时定义的,那么测试它: if (isset($varname)) ,使用前
如果是因为你拼错了,那就纠正一下
甚至可以在php设置中打开警告

jucafojl

jucafojl6#

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

alen0pnh

alen0pnh7#

在回答“为什么他们突然出现?”?我使用这个脚本已经很多年了,从来没有遇到过任何问题。”
这是非常常见的大多数网站经营美国

tzdcorbm

tzdcorbm8#

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

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

mznpcxlj9#

我不想禁用通知,因为它很有用,但我想避免太多的打字。
我的解决方案是这个函数:

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

因此,如果我想引用$name并在存在时回显,我只需编写:

<?=ifexists('name')?>

对于数组元素:

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

在第页中,如果我要引用$\u请求['name']:

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

相关问题