-1

I would like to check whether or not a username already exists in my database. If it does, I would like to redirect back to my signup page. The code I have works to add the usernames but does not check if the username exists. Please help!!! This is the code for register.php page. The code completely skips the check for the 'username' and inserts into the Database if it exists or not.

    <?php  
         error_reporting (E_ALL ^ E_NOTICE);    
         include ('dbconn.php');
         session_start();

         $GLOBALS[$error_message];
         $GLOBALS[$username];

         if(isset($_POST['submit']))
           {     
               $error = array();        
               if(empty($_POST['username']))
                 {
                   $error[] = 'Please enter a username. ';
                 }
               else 
                 {
                   $username = mysqli_real_escape_string($connection, $_POST['username']);
                 }

               if(empty($_POST['password']))
                 {
                   $error[] = 'Please enter a password. ';
                 }
               else
                 {
                   $password = mysqli_real_escape_string($connection,$_POST['password']);   
                 }

               if(empty($_POST['cpassword']))
                 {
                   $error[] = 'Please confirm password. ';
                 }
               else
                 {
                   $cpassword = mysqli_real_escape_string($connection,$_POST['cpassword']);
                 }

               if($password == $cpassword)
                 {
                   $mainpassword= $password;
                 }
               else
                 {
                   $error[] = 'Your passwords do not match. ';
                 }      

               if(empty($error))
                 {                     
                   $query = "SELECT * from User WHERE username=' ".$username." ' ";
                   $result = mysqli_query($connection, $query) or die
                       (mysqli_error($connection));

                  if(mysqli_num_rows($result)> 0)
                  {
                   $multi = "Sorry ! This Username is not available...Please choose another";
                  }
                  else{ $sql="INSERT INTO user(username,password)VALUES                          ('$username','$password')";

              mysqli_query($connection, $sql) or die(mysqli_error($connection));
              header('Location:/MySQLi/confirmation.php'); }
}
               else
                  {
                    $error_message = '<span class="error">';
                    foreach($error as $key => $values) {
                    $error_message.="$values";
                    }
                    $error_message.="</span><br/><br/>";    
                    } 
                 }
?>
HaveNoDisplayName
  • 8,291
  • 106
  • 37
  • 47
code_beast
  • 13
  • 1
  • 2
  • Post your HTML form also. – Funk Forty Niner Jan 06 '15 at 17:13
  • Not sure if it matters, but the table name 'user' is capitalized in your SELECT statement, but not the INSERT statement. – versalle88 Jan 06 '15 at 17:14
  • What's this supposed to do `$multi = "Sorry !...` and how are you exiting it once there? Seems like gate's busted and left wide open. You're just assigning a variable to that and it keeps going from there, in turn inserting into DB. Add a return/exit/die. You should also add an exit after each header. – Funk Forty Niner Jan 06 '15 at 17:15
  • Try echoing the 'select * from User...' to check if there is any error. In last case, paste it into phpMyAdmin and see if it throws something helpful. – Dimas Pante Jan 06 '15 at 17:18
  • Read about PHP - AJAX, that will solve you're problem more elegantly. – Gaurav Dave Jan 06 '15 at 17:19
  • **WARNING**: When using `mysqli` you should be using parameterized queries and [`bind_param`](http://php.net/manual/en/mysqli-stmt.bind-param.php) to add user data to your query. **DO NOT** use string concatenation to accomplish this because you will create severe [SQL injection bugs](http://bobby-tables.com/). – tadman Jan 06 '15 at 17:19
  • **WARNING**: Writing your own access control layer is not easy and there are many opportunities to get it severely wrong. Please, do not write your own authentication system when any modern [development framework](http://codegeekz.com/best-php-frameworks-for-developers/) like [Laravel](http://laravel.com/) comes with a robust [authentication system](http://laravel.com/docs/security) built-in. – tadman Jan 06 '15 at 17:20

2 Answers2

6

You are manually adding spaces around your username so it will look like it does not exist:

$query = "SELECT * from User WHERE username=' ".$username." ' ";
                                             ^             ^

Should be:

$query = "SELECT * from User WHERE username='".$username."' ";

Using a prepared statement would avoid that problem and potential sql injection problems in one go:

$query = "SELECT * from User WHERE username=?";

Also make sure you consistently use your table- and column names: User is not necessarily the same as user.

Also note that you should never store plain-text passwords in a database, you should salt and hash them.

Community
  • 1
  • 1
jeroen
  • 91,079
  • 21
  • 114
  • 132
  • I was just going to make a comment about that. That was my next step ;-) – Funk Forty Niner Jan 06 '15 at 17:20
  • 2
    Considering this is `mysqli`, doing it with string concatenation is awfully messy. – tadman Jan 06 '15 at 17:20
  • 1
    @jeroen Looking at his INSERT statement, you made need to change table name 'User' to 'user'. Not sure if the casing will throw off the query, but it's inconsistent in OP's code. – versalle88 Jan 06 '15 at 17:23
  • 4
    In regards to lettercase http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html - *Table names are stored in lowercase on disk and name comparisons are not case sensitive. MySQL converts all table names to lowercase on storage and lookup. This behavior also applies to database names and table aliases.* – Funk Forty Niner Jan 06 '15 at 17:27
  • 2
    @Fred-ii- I always thought this depended on the case-sensntivity of your filesystem. Good to know. – tadman Jan 06 '15 at 17:29
  • 1
    @tadman As did I at one point, till I started digging on the subject some time ago, which in turn doing my own tests some time back, resulting in `Table` and `table` accessing the same reference. – Funk Forty Niner Jan 06 '15 at 17:32
  • @Fred-ii- I did run into big trouble a few months back on some crappy system where all table names were lower-case in the database but mixed case in the queries. That worked on the IIS server the system was built for but not on my linux test server so I am not so sure about that. Using legacy `mysql_*` obviously to make it even more fun... – jeroen Jan 06 '15 at 17:34
  • @jeroen I agree on the Linux server. Those can be quite touchy (so I heard/read). That area however for me, is still rather gray and can't test that myself. – Funk Forty Niner Jan 06 '15 at 17:35
  • Good to know that MySQL table names are case-insensitive. I wasn't sure. Hopefully, the OP, however, gets in the habit of consistently writing his code just in case he's ever in an environment where it is case-sensitive. – versalle88 Jan 06 '15 at 17:37
  • Ok. Strangely enough, I'm getting the same problem. `Users` and `users` are not being treated the same. I don't know why the documentation says otherwise... – Funk Forty Niner Jan 06 '15 at 17:40
  • 2
    ...however there is this other bit of information which states *Table and database names are stored on disk using the lettercase specified in the CREATE TABLE or CREATE DATABASE statement. Name comparisons are case sensitive. You should not set this variable to 0 if you are running MySQL on a system that has case-insensitive file names (such as Windows or Mac OS X). If you force this variable to 0 with --lower-case-table-names=0 on a case-insensitive file system and access MyISAM tablenames using different lettercases, index corruption may result.* - Therefore, lettercase is an issue. Baffled. – Funk Forty Niner Jan 06 '15 at 17:41
  • @Fred-ii- That definitely confirms my experience :-) – jeroen Jan 06 '15 at 17:48
  • What baffles me though, is that OP should have gotten the following error `Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given...` - which either never happened, or OP didn't bother posting it. Had it been the case, then we would have known better as to what the contributing factor was. (You can't "buy" experience) ;-) Edit: Yet doing `WHERE username` and `WHERE Username` works; *more baffled*. Tables are case-sensitive but not columns in a `WHERE` clause. Tested this just now. – Funk Forty Niner Jan 06 '15 at 17:54
1

SQL table names can be case-sensitive, so 'user' and 'User' are not the same. If your table is named 'user' with a lower-case, then 'SELECT * FORM User' with upper-case may not give any results.

If you simply want to check existence, you can select '1' and add limit 1 so the query doesn't scan the whole table, like this:

"SELECT 1 FROM user WHERE username='" . $username . "' LIMIT 1";

Or you could make your username column UNIQUE, then the INSERT statement would fail if a username already existed, giving you a simple one-query check that could both insert a new user as well as let you know if that name is already taken.

Finally, your code is wide open to SQL Injection attacks. Always escape user input or use prepared statements.

Brian
  • 336
  • 1
  • 9
  • The note about a `UNIQUE` index is a good observation. What is the point of `1/0` in this case? How is this any better than `SELECT COUNT(*)`? – tadman Jan 06 '15 at 17:22
  • It doesn't select any rows, it just checks for the existence of the row. It's better than COUNT because it selects one row only, or none. – Brian Jan 06 '15 at 17:24
  • `SELECT 1` would make more sense. Why the divide by zero, which incidentally returns `NULL`? – tadman Jan 06 '15 at 17:26
  • It returns null with a row count of 1, or an empty set. Null is because it is not selecting any data, just existence. You can SELECT 1 as well, I use '1/0' out of habit which is kind of saying ' one or none ' – Brian Jan 06 '15 at 17:27
  • 2
    It's pretty quirky: In SQL `1/0` means *one divided by zero* which gives a lot of programmers a rash. – tadman Jan 06 '15 at 17:29
  • Thanks guys....Problem seemed to be coming from the Lower case/Upper case confusion....and also maybe, the spaces here ' ".$username." ' "; – code_beast Jan 06 '15 at 17:35