php 带有 $_POST 的未定义索引
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10809937/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Undefined index with $_POST
提问by Xander Luciano
I am trying to relearn some PHP basics for making a simple login script, however I get an error I have not received before(I made the same script a little over a year ago and never had this error. I simplified the code as much as I could to test to see which area was problematic and here is the issue:
我正在尝试重新学习一些 PHP 基础知识来制作一个简单的登录脚本,但是我收到了一个我以前没有收到过的错误(我一年多前制作了相同的脚本,但从未出现过这个错误。我将代码简化为我可以测试看看哪个区域有问题,这是问题所在:
<?php
$user = $_POST["username"];
if($user != null)
{
echo $user;
echo " is your username";
}
else
{
echo "no username supplied";
}
?>
Now this code works fine when I send a variable to the script, but when no variable is supplied it spits out an error. In theory this will be fine because if no username/pass is supplied then an error is expected. I will be checking to make sure of this before the code is send to the script, however I fear that somehow a blank string may leak through and spit out some unknown error. Here is the error I get:
现在,当我向脚本发送一个变量时,这段代码可以正常工作,但是当没有提供变量时,它会抛出一个错误。理论上这会很好,因为如果没有提供用户名/通行证,则会出现错误。在将代码发送到脚本之前,我将进行检查以确保这一点,但是我担心以某种方式可能会泄漏一个空白字符串并吐出一些未知错误。这是我得到的错误:
( ! ) 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
no username supplied
没有提供用户名
as you can see the code registers that no variable was supplied, but it gives out and error that I assume means that a variable was not found were one was expected or something like that. Can someone please clarify this for me?
正如你所看到的代码寄存器没有提供变量,但它给出了错误,我认为这意味着找不到变量是预期的还是类似的。有人可以帮我澄清一下吗?
回答by Mark Reed
In PHP, a variable or array element which has never been set is different from one whose value is null; attempting to access such an unsetvalue is a runtime error.
在 PHP 中,从未设置过的变量或数组元素与值为null;的变量或数组元素不同。试图访问这样一个未设置的值是一个运行时错误。
That's what you're running into: the array $_POSTdoes not have any element at the key "username", so the interpreter aborts your program before it ever gets to the nullity test.
这就是您遇到的情况:数组$_POST在 key 处没有任何元素"username",因此解释器会在程序进行无效测试之前中止您的程序。
Fortunately, you can test for the existence of a variable or array element without actually trying to access it; that's what the special operator issetdoes:
幸运的是,您无需实际尝试访问即可测试变量或数组元素是否存在;这就是特殊运算符isset所做的:
if (isset($_POST["username"]))
{
$user = $_POST["username"];
echo $user;
echo " is your username";
}
else
{
$user = null;
echo "no username supplied";
}
This looks like it will blow up in exactly the same way as your code, when PHP tries to get the value of $_POST["username"]to pass as an argument to the function isset(). However, isset()is not really a function at all, but special syntax recognized before the evaluation stage, so the PHP interpreter checks for the existence of the value without actually trying to retrieve it.
当 PHP 尝试将 的值$_POST["username"]作为参数传递给函数时,它看起来会以与您的代码完全相同的方式爆炸isset()。然而,isset()它根本不是真正的函数,而是在评估阶段之前识别的特殊语法,因此 PHP 解释器会检查该值是否存在,而无需实际尝试检索它。
It's also worth mentioning that as runtime errors go, a missing array element is considered a minor one (assigned the E_NOTICElevel). If you change the error_reportinglevel so that notices are ignored, your original code will actually work as written, with the attempted array access returning null. But that's considered bad practice, especially for production code.
还值得一提的是,随着运行时错误的发生,丢失的数组元素被认为是次要元素(分配了E_NOTICE级别)。如果您更改error_reporting级别以忽略通知,您的原始代码实际上将按编写的方式工作,尝试的数组访问将返回null. 但这被认为是不好的做法,尤其是对于生产代码。
Side note: PHP does string interpolation, so the echostatements in the ifblock can be combined into one:
旁注:PHP 进行字符串插值,因此块中的echo语句if可以合并为一个:
echo "$user is your username";
回答by vinnylinux
Use:
用:
if (isset($_POST['user'])) {
//do something
}
But you probably should be using some more proper validation. Try a simple regex or a rock-solid implementation from Zend Framework or Symfony.
但是您可能应该使用一些更合适的验证。从 Zend Framework 或 Symfony 尝试简单的正则表达式或坚如磐石的实现。
http://framework.zend.com/manual/en/zend.validate.introduction.html
http://framework.zend.com/manual/en/zend.validate.introduction.html
http://symfony.com/doc/current/book/validation.html
http://symfony.com/doc/current/book/validation.html
Or even the built-in filter extension:
甚至内置过滤器扩展:
http://php.net/manual/en/function.filter-var.php
http://php.net/manual/en/function.filter-var.php
Never trust user input, be smart. Don't trust anything. Always make sure what you receive is really what you expect. If it should be a number, make SURE it's a number.
永远不要相信用户输入,要聪明。不要相信任何东西。始终确保您收到的东西确实是您所期望的。如果它应该是一个数字,请确保它是一个数字。
Much improved code:
大大改进的代码:
$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
}
Sanitization and validation.
消毒和验证。
回答by Sampson
Your code assumesthe existence of something:
您的代码假定存在某些东西:
$user = $_POST["username"];
PHP is letting you know that there is no "username" in the $_POSTarray. In this instance, you would be safer checking to see if the value isset()before attempting to access it:
PHP 让您知道$_POST数组中没有“用户名” 。在这种情况下,isset()在尝试访问该值之前检查该值是否更安全:
if ( isset( $_POST["username"] ) ) {
/* ... proceed ... */
}
Alternatively, you could hi-Hyman the ||operator to assign a default:
或者,您可以劫持||操作员以分配默认值:
$user = $_POST["username"] || "visitor" ;
As long as the user's name isn't a falsyvalue, you can consider this method pretty reliable. A much safer route to default-assignment would be to use the ternary operator:
只要用户名不是虚假值,您就可以认为此方法非常可靠。一个更安全的默认赋值路径是使用三元运算符:
$user = isset( $_POST["username"] ) ? $_POST["username"] : "visitor" ;
回答by Damian Czapiewski
Instead of isset()you can use something shorter getting errors muted, it is @$_POST['field']. Then, if the field is not set, you'll get no error printed on a page.
而不是isset()你可以使用更短的东西来消除错误,它是@$_POST['field']. 然后,如果未设置该字段,您将不会在页面上打印错误。
回答by Rust
Try this:
尝试这个:
I use this everywhere where there is a $_POST request.
我在任何有 $_POST 请求的地方都使用它。
$username=isset($_POST['username']) ? $_POST['username'] : "";
This is just a short hand boolean, if isset it will set it to $_POST['username'], if not then it will set it to an empty string.
这只是一个简短的布尔值,如果 isset 它将把它设置为 $_POST['username'],否则它将把它设置为一个空字符串。
Usage example:
用法示例:
if($username===""){ echo "Field is blank" } else { echo "Success" };
回答by kenorb
Prior to PHP 5.2.0 and above you should use filter_input()which is especially created for that to get a specific external user inputs such as get, post or cookie variables by name and optionally filters it to avoid any XSS/Injection attacks on your site. For example:
在 PHP 5.2.0 及更高版本之前,您应该使用filter_input()专门为此创建的它来获取特定的外部用户输入,例如按名称获取、发布或 cookie 变量,并可选择对其进行过滤以避免对您的站点进行任何 XSS/注入攻击。例如:
$user = filter_input(INPUT_POST, 'username');
You may use one of INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, or INPUT_ENV.
您可以使用 INPUT_GET、INPUT_POST、INPUT_COOKIE、INPUT_SERVER 或 INPUT_ENV 之一。
By using optional 3rd argument, you can extend it by variety of filters(for validating, sanitizing, filteringor other), e.g. FILTER_SANITIZE_SPECIAL_CHARS, FILTER_SANITIZE_ENCODED, etc.
通过使用可选的第三个参数,则可以通过各种扩展它的过滤器(用于验证,消毒,过滤或其他),例如FILTER_SANITIZE_SPECIAL_CHARS,FILTER_SANITIZE_ENCODED等
For example:
例如:
<?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>";
?>
The syntax is:
语法是:
mixed
filter_input( int $type , string $variable_name [, int $filter = FILTER_DEFAULT [, mixed $options ]] )(PHP 5 >= 5.2.0, PHP 7)
混合
filter_input( int $type , string $variable_name [, int $filter = FILTER_DEFAULT [, mixed $options ]] )(PHP 5 >= 5.2.0,PHP 7)
See also: Why is better to use filter_input()?
回答by Ivijan Stefan Stipi?
I know that this is old post but someone can help:
我知道这是旧帖子,但有人可以提供帮助:
function POST($index, $default=NULL){
if(isset($_POST[$index]))
{
if(!empty(trim($_POST[$index])))
return $_POST[$index];
}
return $default;
}
This code above are my basic POST function what I use anywhere. Here you can put filters, regular expressions, etc. Is faster and clean. My advanced POST function is more complicate to accept and check arrays, string type, default values etc. Let's your imagination work here.
上面的这段代码是我在任何地方使用的基本 POST 函数。在这里你可以放过滤器、正则表达式等。更快更干净。我的高级 POST 函数接受和检查数组、字符串类型、默认值等更复杂。让我们在这里发挥你的想象力。
You easy can check username like this:
您可以轻松地检查用户名,如下所示:
$username = POST("username");
if($username!==null){
echo "{$username} is in the house.";
}
Also I added $defaultstring that you can define some default value if POST is not active or content not exists.
我还添加了$default字符串,如果 POST 未激活或内容不存在,您可以定义一些默认值。
echo "<h1>".POST("title", "Stack Overflow")."</h1>";
Play with it.
玩它。
回答by Blender
When you say:
当你说:
$user = $_POST["username"];
You're asking the PHP interpreter to assign $userthe value of the $_POSTarray that has a key (or index) of username. If it doesn't exist, PHP throws a fit.
您要求 PHP 解释器分配键(或索引)为$user的$_POST数组的值username。如果它不存在,PHP 就会出错。
Use isset($_POST['user'])to check for the existence of that variable:
使用isset($_POST['user'])以检查变量的存在:
if (isset($_POST['user'])) {
$user = $_POST["username"];
...
回答by richie-torres
try
尝试
if(isset($_POST['username']))
echo $_POST['username']." is your username";
else
echo "no username supplied";
回答by flowfree
Related question:What is the best way to access unknown array elements without generating PHP notice?
相关问题:在不生成 PHP 通知的情况下访问未知数组元素的最佳方法是什么?
Using the answer from the question above, you can safely get a value from $_POST without generating PHP notice if the key does not exists.
使用上述问题的答案,如果键不存在,您可以安全地从 $_POST 获取值,而不会生成 PHP 通知。
echo _arr($_POST, 'username', 'no username supplied');
// will print $_POST['username'] or 'no username supplied'

