未定义索引,_POST 美元 [重复]

Undefined index with $_POST [duplicate]

提问人:Xander Luciano 提问时间:5/30/2012 更新时间:11/9/2018 访问量:235979

问:

我正在尝试重新学习一些PHP基础知识来制作一个简单的登录脚本,但是我收到了一个我以前没有收到过的错误(我在一年多前制作了相同的脚本,但从未遇到过这个错误。我尽可能地简化了代码以测试哪个区域有问题,这就是问题所在:

<?php
$user = $_POST["username"];
if($user != null)
{
    echo $user;
    echo " is your username";
}
else
{
    echo "no username supplied";
}
?>

现在,当我向脚本发送变量时,此代码工作正常,但是当未提供任何变量时,它会吐出错误。从理论上讲,这很好,因为如果没有提供用户名/通行证,则会出现错误。在将代码发送到脚本之前,我将进行检查以确保这一点,但是我担心空白字符串可能会以某种方式泄漏并吐出一些未知错误。这是我得到的错误:

( ! ) Notice: Undefined index: username in C:\wamp\www\verify_login.php on line 2

Call Stack

    Time    Memory  Function    Location
1   0.0003  668576  {main}( )   ..\verify_login.php:0

未提供用户名

正如你所看到的,代码记录了没有提供任何变量,但它给出了错误,我认为这意味着没有找到一个变量,一个是预期的或类似的东西。有人可以帮我澄清一下吗?

php 身份验证 undefined-index

评论

0赞 Paul Dessert 5/30/2012
发布表单的代码。似乎未设置_POST[用户名]
0赞 CodeToLife 10/13/2017
因为如果你做对了一切,你只是在HTML页面方法中命名为'get',你用'$_POST'捕获参数。您需要将其重命名为 $_GET。仅此而已。

答:

7赞 vinnylinux 5/30/2012 #1

用:

if (isset($_POST['user'])) {
   //do something
}

但你可能应该使用一些更适当的验证。尝试一个简单的正则表达式或Zend Framework或Symfony的坚如磐石的实现。

http://framework.zend.com/manual/en/zend.validate.introduction.html

http://symfony.com/doc/current/book/validation.html

甚至是内置的过滤器扩展:

http://php.net/manual/en/function.filter-var.php

永远不要相信用户输入,要聪明。不要相信任何事情。始终确保您收到的确实是您所期望的。如果它应该是一个数字,请确保它是一个数字。

大大改进了代码:

$user = filter_var($_POST['user'], FILTER_SANITIZE_STRING);
$isValid = filter_var($user, FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => "/^[a-zA-Z0-9]+$/")));

if ($isValid) {
    // do something
}

清理和验证。

评论

1赞 mpen 5/30/2012
或者,您可以使用array_key_exists($_POST,'user')
0赞 Xander Luciano 6/3/2012
我喜欢你说的确保。这基本上是一个登录脚本,我计划使用 mysql_real_escape();我相信这就是它的名字。用户名将是事物的任意组合,密码应仅为 MD5,在发送到脚本之前在程序中进行哈希处理。另外,我应该注意,这是对游戏的验证,而不是对网站的验证。
1赞 vinnylinux 6/5/2012
永远,永远,使用 mysql_real_escape()。了解预准备语句并开始使用 PDO。php.net/manual/pdo.prepared-statements.php
0赞 Luke Pring 3/30/2016
array_key_exists('用户',$_POST)
75赞 Mark Reed 5/30/2012 #2

在 PHP 中,从未设置过的变量或数组元素与值为 ;尝试访问此类未设置的值是运行时错误。null

这就是你遇到的:数组在键上没有任何元素,所以解释器在程序进入无效性测试之前就中止了程序。$_POST"username"

幸运的是,您可以测试变量或数组元素是否存在,而无需实际尝试访问它;这就是特殊操作员的作用:isset

if (isset($_POST["username"]))
{
  $user = $_POST["username"];
  echo $user;
  echo " is your username";
} 
else 
{
  $user = null;
  echo "no username supplied";
}

这看起来会以与您的代码完全相同的方式爆炸,当 PHP 尝试获取 的值 to 作为参数传递给函数时。然而,它根本不是一个真正的函数,而是在评估阶段之前识别的特殊语法,因此 PHP 解释器检查值是否存在,而无需实际尝试检索它。$_POST["username"]isset()isset()

还值得一提的是,随着运行时错误的增加,缺少的数组元素被视为次要元素(分配了级别)。如果更改级别以忽略通知,则原始代码实际上将按编写的方式工作,尝试的数组访问返回 。但这被认为是不好的做法,尤其是对于生产代码。E_NOTICEerror_reportingnull

旁注:PHP 是字符串插值的,所以块中的语句可以合并为一个:echoif

echo "$user is your username";

评论

6赞 Xander Luciano 6/3/2012
谢谢。关于为什么我得到这个错误以及如何解决它,非常彻底但简单的答案。我不只是想要一个“如何修复/摆脱这个错误”的答案,我想理解它,这就是你为我所做的,谢谢。
0赞 Bender 1/6/2016
@ViperCode未设置变量$_POST["username"]
1赞 Blender 5/30/2012 #3

当你说:

$user = $_POST["username"];

您要求 PHP 解释器为键(或索引)为 的数组赋值。如果它不存在,PHP 就会抛出一个合适的位置。$user$_POSTusername

用于检查该变量是否存在:isset($_POST['user'])

if (isset($_POST['user'])) {
  $user = $_POST["username"];
  ...

评论

0赞 Xander Luciano 6/3/2012
谢谢你,就像马克·里德(Mark Reed)解释的那样。
3赞 Sampson 5/30/2012 #4

你的代码假定存在某些东西:

$user = $_POST["username"];

PHP 让你知道数组中没有“用户名”。在这种情况下,在尝试访问该值之前,检查该值是否为以下值会更安全:$_POSTisset()

if ( isset( $_POST["username"] ) ) {
    /* ... proceed ... */
}

或者,您可以劫持运算符以分配默认值:||

$user = $_POST["username"] || "visitor" ;

只要用户名不是虚假值,就可以认为此方法非常可靠。一个更安全的默认赋值方法是使用三元运算符:

$user = isset( $_POST["username"] ) ? $_POST["username"] : "visitor" ;
0赞 richie-torres 5/30/2012 #5

尝试

if(isset($_POST['username']))
    echo $_POST['username']." is your username";
else
    echo "no username supplied";

评论

1赞 Xander Luciano 6/3/2012
谢谢。我以前没有遇到过这个错误,现在我明白了。
-2赞 flowfree 5/30/2012 #6

相关问题:在不生成 PHP 通知的情况下访问未知数组元素的最佳方法是什么?

使用上述问题的答案,您可以安全地从 $_POST 获得一个值,而不会在密钥不存在时生成 PHP 通知。

echo _arr($_POST, 'username', 'no username supplied');  
// will print $_POST['username'] or 'no username supplied'

评论

0赞 vinnylinux 5/30/2012
这在很多层面上都是错误的......
0赞 flowfree 5/30/2012
反对者和@vinnylinux:为什么错了?
0赞 tigrang 5/30/2012
可能是因为它不会产生 OP 想要的输出(如果这很重要,我不是投反对票的人,所以原因可能会有所不同)?[username] is your username
0赞 flowfree 5/30/2012
@tigrang什么?错了,因为没有产生相同的字符串?顺便说一句,OP 实际上询问的是,如果键不存在,如何避免 PHP 通知,而不是“如何回显此字符串”。
0赞 tigrang 5/30/2012
我告诉过你,我不知道——我不是反对者之一。看完OP的问题后,他想检查它是否设置,而不是真正输出,OP想检查它是否设置,所以也许把你的答案修改为你可能想等一等,看看投反对票的真正原因是什么。if (_arr($_POST, 'username', false)) { // do something }
5赞 Damian Czapiewski 12/24/2014 #7

而不是您可以使用更短的东西来静音错误,它是 .然后,如果未设置该字段,则页面上不会打印任何错误。isset()@$_POST['field']

2赞 Ikhlak S. 10/4/2015 #8

试试这个:

我在有 _POST 美元请求的任何地方使用它。

$username=isset($_POST['username']) ? $_POST['username'] : "";

这只是一个简短的布尔值,如果是 isset,它会将其设置为 $_POST['username'],如果不是,则会将其设置为空字符串。

使用示例:

if($username===""){ echo "Field is blank" } else { echo "Success" };
5赞 kenorb 3/22/2016 #9

在 PHP 5.2.0 及更高版本之前,您应该使用 filter_input(),它是专门为此创建的,可以按名称获取特定的外部用户输入,例如 get、post 或 cookie 变量,并选择性地过滤它以避免对您站点的任何 XSS/注入攻击。例如:

$user = filter_input(INPUT_POST, 'username');

您可以使用INPUT_GET、INPUT_POST、INPUT_COOKIE、INPUT_SERVER或INPUT_ENV之一。

通过使用可选的第三个参数,您可以通过各种过滤器(用于验证清理过滤或其他来扩展它,例如 , 等。FILTER_SANITIZE_SPECIAL_CHARSFILTER_SANITIZE_ENCODED

例如:

<?php
$search_html = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS);
$search_url = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_ENCODED);
echo "You have searched for $search_html.\n";
echo "<a href='?search=$search_url'>Search again.</a>";
?>

语法为:

mixed ( int $type , string $variable_name [, int $filter = FILTER_DEFAULT [, mixed $options ]] )filter_input

(PHP 5 >= 5.2.0, PHP 7)

Смотритетакже: 为什么最好使用 filter_input()?

2赞 Ivijan Stefan Stipić 3/24/2016 #10

我知道这是旧帖子,但有人可以帮忙:

function POST($index, $default=NULL){
        if(isset($_POST[$index]))
        {
            if(!empty(trim($_POST[$index])))    
                return $_POST[$index];
        }
        return $default;
    }

上面的这段代码是我的基本 POST 函数,我在任何地方都使用。在这里你可以放置过滤器、正则表达式等。更快,更干净。我的高级 POST 函数在接受和检查数组、字符串类型、默认值等方面更加复杂。让你的想象力在这里工作。

您可以像这样轻松检查用户名:

$username = POST("username");
if($username!==null){
    echo "{$username} is in the house.";
}

此外,我还添加了字符串,如果 POST 未处于活动状态或内容不存在,您可以定义一些默认值。$default

echo "<h1>".POST("title", "Stack Overflow")."</h1>";

玩一玩。