Undefined index with $_POST [duplicate]

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?


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";

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.