未定义的索引与$ _POST

我试图重新学习一些简单的login脚本的PHP基础知识,但是我得到一个我以前没有收到的错误(我在一年前做了同样的脚本,从来没有这个错误。我可以testing看哪个区域有问题,这是问题:

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

现在这个代码工作正常,当我发送一个variables的脚本,但是当没有variables提供它吐出一个错误。 从理论上讲,这样可以,因为如果没有提供用户名/密码,那么就会出现错误。 我将在代码发送到脚本之前检查以确保这一点,但是我担心某个空白string可能会泄漏并吐出一些未知的错误。 这是我得到的错误:

 ( ! ) 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 

没有提供用户名

正如你所看到的代码注册,没有variables提供,但它给出了错误,我假设一个variables没有被发现是一个预期或类似的东西。 有人能为我澄清这个吗?

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

这就是你遇到的情况:数组$_POST在索引"username"处没有任何元素,所以解释器会在程序进入无效性testing之前中止你的程序。

幸运的是,您可以testingvariables或数组元素的存在,而不用实际访问它; 这就是特殊运营商所做的事情:

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

当PHP尝试获取$_POST["username"]的值作为parameter passing给函数isset()时,这看起来像是会以与代码完全相同的方式炸毁。 然而, isset()实际上并不是一个函数,但是在评估阶段之前就已经识别出了特殊的语法,所以PHP解释器检查值的存在,而实际上并没有试图检索它。

还值得一提的是,当运行时错误发生时,缺less的数组索引被认为是次要数组(指定了E_NOTICE级别)。 如果您更改error_reporting级别以便通知被忽略,则您的原始代码实际上将以书面forms工作,尝试的数组访问返回null 。 但这被认为是不好的做法,特别是对于生产代码。

注意:PHP会进行string插值,所以if块中的echo语句可以合并为一个:

 echo "$user is your username"; 

使用:

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

但你可能应该使用一些更合适的validation。 从Zend Framework或Symfony尝试一个简单的正则expression式或一个坚如磐石的实现。

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

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

甚至内置的filter扩展:

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

永远不要相信用户的input,要聪明。 不要相信任何东西。 一定要确保你收到的东西真的是你期望的。 如果它应该是一个数字,请确保它是一个数字。

很多改进的代码:

 $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 } 

消毒和validation。

你的代码假设存在一些东西:

 $user = $_POST["username"]; 

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

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

或者,你可以hi-jack || 运营商分配一个默认值:

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

只要用户的名字不是一个虚假的价值,你可以认为这个方法相当可靠。 默认分配的一个更安全的途径是使用三元运算符:

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

当你说:

 $user = $_POST["username"]; 

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

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

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

尝试这个:

我在任何地方使用$ _POST请求。

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

这只是一个简短的布尔值,如果isset将它设置为$ _POST ['username'],如果不是,那么它将把它设置为一个空string。

用法示例:

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

在PHP 5.2.0及更高版本之前,您应该使用filter_input() ,它专门为此创build一个特定的外部用户input,例如get,post或者cookievariables名称,并且可以对其进行过滤以避免任何XSS / Injection攻击现场。 例如:

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

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

通过使用可选的第三个参数,你可以扩展它的各种filter (用于validation , 消毒 , 过滤或其他 ),例如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> = 5.2.0,PHP 7)

另请参见: 为什么最好使用filter_input()?

尝试

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

而不是isset()你可以使用更短的错误获取错误,它是@$_POST['field'] 。 然后,如果该字段未设置,则不会在页面上打印错误。

我知道这是旧post,但有人可以帮助:

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

以上代码是我在任何地方使用的基本POSTfunction。 在这里你可以把filter,正则expression式等,更快,更干净。 我的高级POST函数更加复杂,接受和检查数组,stringtypes,默认值等。让你的想象力在这里工作。

你很容易就可以检查这样的用户名:

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

此外,我添加了$defaultstring,您可以定义一些默认值,如果POST不活跃或内容不存在。

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

玩吧。

相关问题: 访问未知数组元素而不生成PHP通知的最佳方式是什么?

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

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