带有$ _POST的未定义索引

时间:2012-05-30 04:19:51

标签: php login undefined-index

我正在尝试重新学习一些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

没有提供用户名

你可以看到代码寄存器没有提供变量,但它给出了错误,我假设意味着没有找到一个变量是预期的或类似的东西。有人可以帮我解释一下吗?

10 个答案:

答案 0 :(得分:48)

在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试图将$_POST["username"]的值作为参数传递给函数isset()时,看起来它会以与代码完全相同的方式爆炸。但是,isset()根本不是一个函数,而是在评估阶段之前识别的特殊语法,因此PHP解释器检查值的存在而不实际尝试检索它。

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

附注:PHP进行字符串插值,因此echo块中的if语句可以组合成一个:

echo "$user is your username";

答案 1 :(得分:6)

使用:

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
}

清理和验证。

答案 2 :(得分:3)

您的代码假设存在某些内容:

$user = $_POST["username"];

PHP告诉您$_POST数组中没有“用户名”。在这种情况下,在尝试访问它之前,您可以更安全地检查值isset()

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

或者,您可以通过||运算符来设置默认值:

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

只要用户的名称不是 falsy 值,您就可以认为此方法非常可靠。默认分配的更安全的途径是使用三元运算符:

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

答案 3 :(得分:2)

而不是isset()您可以使用较短的错误来缓解错误,它是@$_POST['field']。然后,如果未设置该字段,您将不会在页面上打印错误。

答案 4 :(得分:2)

试试这个:

我在有$ _POST请求的地方使用它。

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

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

用法示例:

if($username===""){ echo "Field is blank" } else { echo "Success" };

答案 5 :(得分:2)

在PHP 5.2.0及更高版本之前,你应该使用filter_input()特别为此创建的filters来获取特定的外部用户输入,例如get,post或cookie变量,并可选择过滤它以避免任何XSS /注入攻击您的网站。例如:

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

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

通过使用可选的第三个参数,您可以按validatingsanitizingfilteringotherWhy is better to use filter_input()?)的多种方式对其进行扩展,例如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 filter_input(int $ type,string $ variable_name [,int $ filter = FILTER_DEFAULT [,mixed $ options]])

     

(PHP 5&gt; = 5.2.0,PHP 7)

另请参阅:https://jsfiddle.net/u5m067xq/4/

答案 6 :(得分:1)

当你说:

$user = $_POST["username"];

您要求PHP解释器为$user分配具有$_POST密钥(或索引)的username数组的值。如果它不存在,那么PHP会抛出一个拟合。

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

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

答案 7 :(得分:1)

我知道这是旧帖,但有人可以提供帮助:

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.";
}

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

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

玩它。

答案 8 :(得分:0)

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

答案 9 :(得分:-2)

相关问题: What is the best way to access unknown array elements without generating PHP notice?

使用上面问题的答案,如果密钥不存在,您可以安全地从$ _POST获取值,而不会生成PHP通知。

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