【问题标题】:Undefined index with $_POST [duplicate]$_POST 的未定义索引 [重复]
【发布时间】:2012-06-04 07:31:27
【问题描述】:

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

没有提供用户名

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

【问题讨论】:

  • 发布您的表单代码。看起来 _POST[username] 没有设置
  • 因为如果你做的一切都是正确的,你只是在 HTML 页面方法中命名为 'get' 并且你正在使用 '$_POST' 捕获参数。您需要将其重命名为 $_GET 。就是这样。

标签: php login undefined-index


【解决方案1】:

在PHP中,从未设置过的变量或数组元素与值为null的变量或数组元素不同;试图访问这样的 unset 值是一个运行时错误。

这就是您遇到的问题:数组 $_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 会进行字符串插值,因此if 块中的echo 语句可以合并为一个:

echo "$user is your username";

【讨论】:

  • 谢谢。关于我为什么会收到此错误以及如何解决它的非常彻底但简单的答案。我不只是想要一个“如何修复/摆脱这个错误”的答案,我想理解它,这就是你为我所做的,谢谢。
  • @ViperCode 你的$_POST["username"] 变量没有设置
【解决方案2】:

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

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

和它一起玩。

【讨论】:

    【解决方案3】:

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

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

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

    通过使用可选的第三个参数,您可以通过各种filters 对其进行扩展(对于validatingsanitizingfilteringother),例如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>";
    ?>
    

    语法是:

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

    (PHP 5 >= 5.2.0,PHP 7)

    另见:Why is better to use filter_input()?

    【讨论】:

      【解决方案4】:

      试试这个:

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

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

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

      使用示例:

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

      【讨论】:

        【解决方案5】:

        除了isset(),您可以使用更短的内容来消除错误,它是@$_POST['field']。然后,如果未设置该字段,您将不会在页面上打印任何错误。

        【讨论】:

          【解决方案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
          }
          

          消毒和验证。

          【讨论】:

          • 或者,您可以使用array_key_exists($_POST,'user')
          • 我喜欢你所说的确保。这基本上是一个登录脚本,我打算使用 mysql_real_escape();我相信这就是所谓的。用户名可以是任何事物的组合,密码只能是 MD5,在发送到脚本之前在程序中进行哈希处理。另外我应该注意,这是对游戏的验证,而不是对网站的验证。
          • 永远不要使用 mysql_real_escape()。了解 Prepared Statements 并开始使用 PDO。 php.net/manual/pdo.prepared-statements.php
          • array_key_exists('user',$_POST)
          【解决方案7】:

          相关问题: 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'
          

          【讨论】:

          • 这在很多层面都是错误的......
          • Downvoters 和@vinnylinux:为什么错了?
          • 可能是因为它不会产生 OP 想要的输出 [username] is your username (如果这很重要,那么原因可能会有所不同,我不是那个投反对票的人)?
          • @tigrang 什么?错了,因为不产生相同的字符串?顺便说一句,OP 实际上询问如何 avoid PHP 通知如果密钥不存在而不是“如何回显这个字符串”。
          • 我告诉过你,我不知道 - 我不是反对者之一。在阅读了 OP 的问题后,他想检查它是否设置,而不是真正输出,OP 想检查它是否设置,所以也许修改你对if (_arr($_POST, 'username', false)) { // do something } 的回答你可能想等待,看看拒绝投票的真正原因是什么是。
          【解决方案8】:

          试试

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

          【讨论】:

          • 谢谢。我以前没有遇到过这个错误,现在我明白了。
          【解决方案9】:

          你的代码假设某物的存在:

          $user = $_POST["username"];
          

          PHP 让您知道$_POST 数组中没有“用户名”。在这种情况下,在尝试访问之前检查值 isset() 会更安全:

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

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

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

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

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

          【讨论】:

            【解决方案10】:

            当你说:

            $user = $_POST["username"];
            

            您要求 PHP 解释器将 $_POST 数组的值分配给 $user,该数组的键(或索引)为 username。如果它不存在,PHP 就会出现故障。

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

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

            【讨论】:

            • 谢谢,就像马克里德解释的那样。
            猜你喜欢
            • 2016-03-30
            • 2018-09-11
            • 2016-10-24
            • 1970-01-01
            • 2011-09-04
            • 2018-03-05
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多