未定义的索引与$ _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_CHARS
, FILTER_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."; }
此外,我添加了$default
string,您可以定义一些默认值,如果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'