Undefined index with $_POST [duplicate]
Asked Answered
A

10

49

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

Aura answered 30/5, 2012 at 4:19 Comment(2)
post your code for the form. It looks like _POST[username] is not setBiathlon
Because if you are doing all correct you just named in the HTML page method as 'get' and you're catching the parameter with '$_POST' . You need rename it to $_GET instead. That is all.Catalinacatalo
C
75

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 unset value is a runtime error.

That's what you're running into: the array $_POST does not have any element at the key "username", so the interpreter aborts your program before it ever gets to the nullity test.

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 isset does:

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.

It's also worth mentioning that as runtime errors go, a missing array element is considered a minor one (assigned the E_NOTICE level). If you change the error_reporting level 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.

Side note: PHP does string interpolation, so the echo statements in the if block can be combined into one:

echo "$user is your username";
Captor answered 30/5, 2012 at 4:23 Comment(2)
Thank you. Very thorough but simple answer as to why I get this error and how to solve it. I didn't just want a "How to fix/get rid of this error" answer, I wanted to understand it and that is what you did for me, Thank you.Aura
@ViperCode your $_POST["username"] variable wasn't setTarantella
S
7

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.

http://framework.zend.com/manual/en/zend.validate.introduction.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

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.

Stormie answered 30/5, 2012 at 4:22 Comment(4)
alternatively, you can use array_key_exists($_POST,'user')Swirly
I like what you said about making sure. This is basically going to be a login script and I plan to use mysql_real_escape(); I believe is what it is called. usernames will be any combination of things and passwords should be MD5 only, hashed in the program before sent to the script. Also I should note that this is validation for a game, not for a site.Aura
Never, EVER, use mysql_real_escape(). Learn about Prepared Statements and start using PDO. php.net/manual/pdo.prepared-statements.phpStormie
array_key_exists('user',$_POST)Cosmism
B
5

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.

Bord answered 23/12, 2014 at 22:29 Comment(0)
M
5

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:

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

You may use one of INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, or INPUT_ENV.

By using optional 3rd argument, you can extend it by variety of filters (for validating, sanitizing, filtering or other), e.g. FILTER_SANITIZE_SPECIAL_CHARS, FILTER_SANITIZE_ENCODED, etc.

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)

See also: Why is better to use filter_input()?

Monoplane answered 22/3, 2016 at 8:6 Comment(0)
F
3

Your code assumes the existence of something:

$user = $_POST["username"];

PHP is letting you know that there is no "username" in the $_POST array. In this instance, you would be safer checking to see if the value isset() before attempting to access it:

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

Alternatively, you could hi-jack the || operator to assign a default:

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

As long as the user's name isn't a falsy value, 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" ;
Flinn answered 30/5, 2012 at 4:25 Comment(0)
W
2

Try this:

I use this everywhere where there is a $_POST request.

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

Usage example:

if($username===""){ echo "Field is blank" } else { echo "Success" };
Whose answered 4/10, 2015 at 9:42 Comment(0)
D
2

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.

You easy can check username like this:

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

Also I added $default string that you can define some default value if POST is not active or content not exists.

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

Play with it.

Dumps answered 23/3, 2016 at 16:10 Comment(0)
U
1

When you say:

$user = $_POST["username"];

You're asking the PHP interpreter to assign $user the value of the $_POST array that has a key (or index) of username. If it doesn't exist, PHP throws a fit.

Use isset($_POST['user']) to check for the existence of that variable:

if (isset($_POST['user'])) {
  $user = $_POST["username"];
  ...
Unnumbered answered 30/5, 2012 at 4:23 Comment(1)
Thank you, just like mark reed explained it.Aura
I
0

try

if(isset($_POST['username']))
    echo $_POST['username']." is your username";
else
    echo "no username supplied";
Irrupt answered 30/5, 2012 at 4:25 Comment(1)
Thank you. I just hadn't run into this error before and now i understand it.Aura
D
-2

Related question: What is the best way to access unknown array elements without generating PHP notice?

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.

echo _arr($_POST, 'username', 'no username supplied');  
// will print $_POST['username'] or 'no username supplied'
Deshawndesi answered 30/5, 2012 at 4:25 Comment(5)
This is wrong in so many levels...Stormie
Downvoters & @vinnylinux: Why is it wrong?Deshawndesi
Probably because it wont doesn't produce the output the OP wants [username] is your username (I'm not the one who downvoted, if that matters, so reason may be different)?Bromidic
@Bromidic what? wrong because not produce the same string? btw, the OP actually asking about how to avoid PHP notice if the key doesn't exist not "how to echo this string".Deshawndesi
I told you, I don't know - I wasn't one of the downvoters. After reading the OP's question, he wants to check if its set, not really output, OP wants to check if its set or not, so maybe revise your answer to if (_arr($_POST, 'username', false)) { // do something } You may want to wait and see what the real reason for downvote is.Bromidic

© 2022 - 2024 — McMap. All rights reserved.