我正在尝试重新学习一些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
没有提供用户名
你可以看到代码寄存器没有提供变量,但它给出了错误,我假设意味着没有找到一个变量是预期的或类似的东西。有人可以帮我解释一下吗?
答案 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之一。
通过使用可选的第三个参数,您可以按validating(sanitizing,filtering,other或Why is better to use filter_input()?)的多种方式对其进行扩展,例如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&gt; = 5.2.0,PHP 7)
答案 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'