Building Browsergames: The Registration Page (PHP)

Have you ever wanted to build your own browsergame, but not known how to begin or where to start? Generally, the easiest place to start is your registration page. It’s the page that users will see first when they’re interested in playing your game, and it’s how they will create their accounts before they login and begin playing your game. This write-up will try to guide you through building a basic registration page. It will also show you how you can put some database design tips to use when you build your database.

To begin with, we’ll need the database. Open up whatever utility you are using to administrate your databases(I use PHPMyAdmin), and create the proper new database and login for your new browsergame project. Here’s some SQL to setup your basic users table:

CREATE TABLE users (
	id int NOT NULL AUTO_INCREMENT,
	username varchar(250),
	password varchar(50),
	PRIMARY KEY(id)
);

Once that’s done, we can get to writing our code.

To begin with, we’ll need our registration form. Let’s just create a basic one:

1
2
3
4
5
6
<form method='post' action='register.php'>
Username: <input type='text' name='username' /><br />
Password: <input type='password' name='password' /><br />
Confirm Password: <input type='password' name='confirm' /><br />
<input type='submit' value='Register!' />
</form>

So now we have our form. But we don’t actually have anything in place to handle what our form does.

First off, let’s add something to check and see that the values being passed in as a password and a password confirmation match up:

1
2
3
4
5
6
7
8
9
10
<?php
	if($_POST) {
		$password = $_POST['password'];
		$confirm = $_POST['confirm'];	
		if($password != $confirm) { ?>
<span style='color:red'>Error: Passwords do not match!</span>		
<?php	}
	}
?>
<form method='post' action='register.php'>

Now, what did we do there?

First off, we checked to see if PHP’s internal variable $_POST had anything inside of it. If it didn’t, then there hasn’t been any data sent to our script to process – trying to process empty data would be pointless.

Then, we store the password and the password confirmation sent to us. We compare them, and if they’re not equal we spit out an error message.

The next feature we are going to add is checking to see whether the username that the user wants is available. In order to do that, we’ll need to connect to the database we created earlier, and run a query on the users table.

7
8
9
10
11
12
<?php	} else {
			$dbhost = 'localhost';
			$dbuser = 'user';
			$dbpass = 'pass';
			$dbname = 'name';	
		}

The first thing we did was define our database connection values. These will vary based on your specific configuration. $dbhost will be where your database is hosted – changes are, ‘localhost’ will be fine. $dbuser is the username you connect to the database with, and $dbpass is the password that matches that username. Finally, $dbname is the name of the database we will be working with after we have connected.

Once we have all our configuration data set up, we can actually connect to the database:

12
13
14
15
			$conn = mysql_connect($dbhost,$dbuser,$dbpass)
				or die ('Error connecting to mysql');
			mysql_select_db($dbname);
		}

These lines of code will connect to the database, and then select the specific database we need to work with. The or die part of the code tells PHP that, if there’s an error connecting, it should ‘die’ with that error message. If you’re getting that error message when you’re testing, changes are it’s because your settings from earlier are not correct.

Once we’ve successfully established a connection to our database, we can begin to run queries on it:

15
16
17
			$query = sprintf("SELECT COUNT(id) FROM users WHERE UPPER(username) = UPPER('%s')",
				mysql_real_escape_string($_POST['username']));
		}

Here, we stored our new query into $query. We’re going to be counting how many users exist within the users table that have the username we want, when both the username we want and their username are switched to uppercase. This will allow us to limit users to one unique username, along with making sure that the username “Foo” and “foo” mean the same thing – so there’s less confusion. We used the sprintf() function to format our output, so that we could use mysql_real_escape_string() to escape the value of $_POST['username'] before we put it into our query. We escaped our value so that we could avoid SQL Injection exploits. You should always escape any data you are going to use in a database query.

Once we have our query prepared, it’s time to execute it and retrieve our results.

17
18
19
20
21
			$result = mysql_query($query);
			list($count) = mysql_fetch_row($result);
			if($count >= 1) { ?>
<span style='color:red'>Error: that username is taken.</span>
<?php		}

What we’ve done here is we’ve executed our query, and then stored what it returned into $count. Then, we’re checking to see what the value that came back was. If it’s greater than or equal to 1, then a user already exists with that username – and we therefore display an error message telling the user that the username they want is taken.

But we still haven’t built the main part of the register page yet – the actual registering part! So now we will do that. Just underneath our handling for the username being taken, add this:

21
22
23
24
25
26
27
28
29
<?php		} else {
				$query = sprintf("INSERT INTO users(username,password) VALUES ('%s','%s');",
					mysql_real_escape_string($_POST['username']),
					mysql_real_escape_string(md5($password)));
				mysql_query($query);
			?>
<span style='color:green'>Congratulations, you've registered successfully!</span>
<?php
			}

That code will create an INSERT query that we can run, which will insert our new user into the database. Once again, we use sprintf() and mysql_real_escape_string() to make sure that we don’t have any SQL Injection problems. Something new that you should notice is that in the case of $password, we also pass it through another function – md5(). By passing it through md5, we get back a hashed version of our password. This means that it has been encrypted one way, and cannot be decrypted – so we can safely store our user’s passwords in our database, and even if someone gets access to it they won’t be able to steal user’s passwords. You should never store a user’s password in plaintext – it’s just asking for trouble.

After we’ve created and then executed our query, we print out another helpful message to tell the user that they registered successfully. And that’s that! You now have a working registration script, written in PHP. Here’s the code in it’s entirety:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
	if($_POST) {
		$password = $_POST['password'];
		$confirm = $_POST['confirm'];	
		if($password != $confirm) { ?>
<span style='color:red'>Error: Passwords do not match!</span>		
<?php	} else {
			$dbhost = 'localhost';
			$dbuser = 'user';
			$dbpass = 'pass';
			$dbname = 'name';
			$conn = mysql_connect($dbhost,$dbuser,$dbpass)
				or die ('Error connecting to mysql');
			mysql_select_db($dbname);
			$query = sprintf("SELECT COUNT(id) FROM users WHERE UPPER(username) = UPPER('%s')",
				mysql_real_escape_string($_POST['username']));
			$result = mysql_query($query);
			list($count) = mysql_fetch_row($result);
			if($count >= 1) { ?>
<span style='color:red'>Error: that username is taken.</span>
<?php		} else {
				$query = sprintf("INSERT INTO users(username,password) VALUES ('%s','%s');",
					mysql_real_escape_string($_POST['username']),
					mysql_real_escape_string(md5($password)));
				mysql_query($query);
			?>
<span style='color:green'>Congratulations, you registered successfully!</span>
<?php
			}	
		}
	}
?>
<form method='post' action='register.php'>Username: <input type='text' name='username' /><br />
Password: <input type='password' name='password' /><br />
Confirm Password: <input type='password' name='confirm' /><br />
<input type='submit' value='Register!' />
</form>

If you want to check it out in action, you can see it here.

Would you like to see this in a language other than PHP? Send me an e-mail at buildingbrowsergames@gmail.com and I’ll get to work at building it for you.

Wish there was more?

I'm considering writing an ebook - click here.

.

Luke is the primary editor of Building Browsergames, and has written a large portion of the articles that you read here. He generally has no idea what to say when asked to write about himself in the third person.

Thursday, April 17th, 2008 buildingbrowsergames, code, php
  • Tahmid Hossain

    I am newbie, I have sucessfully set up an online database for a game i am trying to make. Then i saved this php code as a .php file and then i imported it in my server, but it isn't working. Do i need to change any part of this code to make it work?

  • ScarFaceCRO

    So, after I figure out which my data go where ($dbhost, $dbuser, $dbpass and $dbname - I THINK I did it right coz before I got error connecting to MySQL, and now I dont get that error), I got msg: Congratulations, you registered successfully!
    but my page stays at register, and data wasnt send to db "users". So I guess I didnt conect to MySQL or I do something wrong. MAybe my dbname is wrong? Should that be my "users" table in phpMyAdmin? Or something else? Coz I put code like this:
    dbhost is "localhost"
    dbuser is "name I have where I created database in phpmyadmin
    dbpass is "pass I connect to server and basicly to all else"
    dbname is "so I put just "users" for tabel at phpmyadmin"
    Do you see where I go wrong? Im self learner and english is not my native language so it is double hard for me -.-"
    Please help =) TY!

  • Stephen M.

    I am getting issues with the portions showing up in my page immediately after loading it. I have the page saved in my server www directory, checked, double checked, and even quadruple checked the code with everything everyone has posted. I still can't get it to go away until after "Register!" is clicked. Please help!

  • Serbia

    But how to use php code just when I click on register button ? Sorry for bad English

  • saeed albairaq

    Great ...... thank you very much

  • This  is my huge happiness to visit your site and to like your excellent post. Continue on posting and thanks for sharing this .

  • Healthy and interesting, have a hard deciding what I really think of it all.

    bangla natok

  • Benjamin Vangeel

    Hey - so I'm trying to create the Query on the 'Users' table (the

  • Rokas Rimkevicius

     You need to put your server information between $dbhost= 'HERE' and all the other...

  • Marius

    Yeah, delete the following two lines:

    list($count) = mysql_fetch_row($result);
    if($count >= 1) { ?>

    Move the following line:

    Error: that username is taken.

    to go inside my if block:

    if($result) { ?>
    Error: that username is taken.

    Error: that username is taken.

    Congratulations, you registered successfully!

  • Kismet

    Perfect Marius! It works! Thankyou so much for this.

    I am baffled though, why didn't the original code 'work out of the box'? Is it something wrong with Wamp? Should I be using something else to do these tutorials with?

    Thanks again.

  • Red

    Thanks for the reply Maruz. Interesting stuff!

  • Kismet

    I get this error when I try to register:

    Warning: mysql_connect() [function.mysql-connect]: Access denied for user 'user'@'localhost' (using password: YES) in C:\wamp\www\BBG\register.php on line 12
    Error connecting to mysql

    I'm very new to this, so I'm not sure what I've done wrong.

    This is what I've done so far, I'm using Wamp, so I created a new project folder in C:\wamp\www called BBG.

    In phpMyAdmin I've created 3 tables "items, users and user_inventory".

    I'm using ConTEXT as my editor so I copied and pasted the whole code into it and saved it as register.php.

    But I get the above error message when I try to register. What have I done wrong?

  • That error message means that your PHP script is unable to connect to
    your MySQL database - try making sure all of your credentials are
    correct, and then continuing from there.

  • Kismet

    Duh! I'm so dumb! You're right Luke, I needed to change the configuration file to match my Wamp info:

    Now it's working, but I'm getting a new error:

    Warning: mysql_fetch_row() expects parameter 1 to be resource, boolean given in C:\wamp\www\BBG\register.php on line 19

    This is line 19: list($count) = mysql_fetch_row($result);

    I see that Marius had the same problem and managed to solve it, but he didn't post his solution :(.

    Anybody have any ideas?

  • I couldn't say what's breaking for you, and you'll want to look at the
    line just before the one where the error's being thrown - somehow,
    your $result variable is being set to a boolean value instead of a
    mysql resource.

  • Marius

    Yeah, I dropped the "count" approach and did this instead:

    $query = sprintf("SELECT * FROM users WHERE username = '%s'", mysql_real_escape_string($_POST['username'])));
    $result = mysql_fetch_array(mysql_query($isuser));

    Then I use a simple if statement to check if I got any data or not:
    if($result) {
    // User already exists
    } else {
    // User does not exist, safe to register if all input validates
    }

    $result is an array, and if the user exists in the DB I have data there and the if check returns true, if no data enters the array is empty and the if check returns false and runs the else statement instead.

  • Kismet

    Thankyou so much Marius. I've tried to implement your new code as best I can. And this is what my register.php looks like now:

    --------------------------------

    Error: Passwords do not match!
    = 1) { ?>
    Error: that username is taken.

    Congratulations, you registered successfully!

    <form method="post" action="register.php">Username: <input type="text" name="username"/>

    Password: <input type="password" name="password"/>

    Confirm Password: <input type="password" name="confirm"/>

    <input type="submit" value="Register!"/>
    </form>
    ------------------------------

    The error message has changed, now it says 'Warning: mysql_fetch_row() expects parameter 1 to be resource, boolean given in C:\wamp\www\BBG\register.php on line 22'.

    Line 22 is this one: list($count) = mysql_fetch_row($result);

    I know I've done something wrong, but I feel I'm very close to getting this working. Can you see where I've messed up?

  • Maruz

    If you use a random salt value, you'd have to store that value to later validate the password. It can't be random each time the user tries to log in, then he will never be able to log in again.

    A random salt could be the md5 value of a random number.

    $salt = md5(rand(11111, 99999));
    $password = md5($password.$salt);

    Be sure to store the $salt value in your db for later use, and to match the users password using that same salt every time.

    For better security (as you store the random salt probably next to each user in your db) you could also have a fixed $salt2 stored in a non-accessible php file, and add that to every password:

    include "non-accessible php file";
    $salt2 = "some-random-salt";

    $password = md5($password.$salt.$salt2);

  • Pandora

    Hullo Maruz,

    sorry for my English - I'm foreign. I find that idea with storing a unique salt value in the database interesting, I will try it in my next project. :)
    I also want to add my idea as well... :) I chop the password through the middle and put the salt between the two parts... which places I change.
    md5($passwordpart2.SALT.$passwordpart1);

    Have a nice day,
    Pandora

  • Red

    I would like to see an example of the MD5 function in combination with a random "salt" value.

  • Lawrence

    You use Phpmyadmin do you know any for mac

  • PHPMyAdmin is software that you run on your server - it doesn't matter
    what operating system the computer you're developing on is running.

  • Lawrence

    ah right, so first I need to get my server running then, can I set up a local server and use it

  • Exactly :)

  • meitnerium123

    does anyone know how to insert data from drop down menus into the database? and why are the values %s?

    $query = sprintf("INSERT INTO users(username,password) VALUES ('%s','%s');",

  • welon

    1. You can use a drop down menu in a <form> tag. ex:

    <form action="thispage.php" method="POST">
    <select name="yourvab">
    <option value="postedname">Option 1</option>
    <option value="postedname">Option 2</option>
    </select>
    <input type="submit"/>
    </form>

    If you now submit the variables $_POST['yourvab'] value will be "postedname".

    2. %s means "string" and is declared after the ",
    This method is used to get rid of coding differences between the input in php and mysql.

  • OldRod

    I must be doing something wrong... I copied the code shown above and pasted it into a file called "register.php".

    When I run this file, I get

    "Error: Passwords do not match! = 1) { ?> Error: that username is taken. Congratulations, you registered successfully!"

    All in one string across the top of the page, then I get my form fields below that. Entering data in the form fields and clicking the "Register!" button does nothing other than refresh the page.

    No records are entered into my database. No sql errors are generated... nothing happens other than a page refresh.

    What am I missing here?

  • Welon

    Have stored the file on an phpserver? or just launched it in your browser?

  • OldRod

    I got it to work. I posted again shortly after the first message, but it never showed up, hmmm...

    If I cut and paste from the full code shown above, I get the error shown above. If I enter the code by hand, it works... I'm not sure why. Maybe my cut and paste didn't get everything?

    Anyway, it's working now :)

  • It sounds like you may have missed a closing brace somewhere - if you can
    paste your code somewhere or e-mail me directly at
    buildingbrowsergames@gmail.com, I'll try to help you get your issue sorted
    out.

  • BUnzaga
  • Anthonie

    I don't get it. I register, but the register.php page refreshes displaying nothing. Nothing was inserted into the database as well. I copied the MYSQL query and code many times.

  • Is it possible one of your conditions is not being met? That's the only
    reason I can think of for why a new entry isn't getting saved down.

  • Anthonie

    Well, if a condition isn't being met (which it should since it's use the regular 'Test' as username as password), it should at least display an error, no?

    Thanks for the reply, thought I wouldn't get support at all when I commented. :P

  • Try pasting your code somewhere, so I can take a look - or e-mailing me
    directly at buildingbrowsergames@gmail.com. I'll try to help you get this
    figured out :)

  • Marius

    I'm having trouble with your example on one line, and the newly registered user does not get inserted to the table.

    "Warning: mysql_fetch_row() expects parameter 1 to be resource, boolean given"

    The line that gives this error is "list($count) = mysql_fetch_row($result);", line 18 in your example

    I also get the message Congratulations, you registered successfully! though that is not true.

    I've copied your code, so if you guys get the code to work as it should, then I guess it's my DB that's the cause of this problem, but I have no idea what it could be... Anyone able to help me?

    My table is called users, and I have id int, username varchar and password varchar as fields.

  • Marius

    I've worked out the above problem, but that's by doing things a bit differently than the example in this tutorial, still don't know why I got this error.

  • Michael

    whats about the page register.php you are posting the registration data to?
    if i run this code and fill in the registration form, after clicking at "register!" theres an error, because page register.php doesnt exist

  • This code is supposed to be getting saved *into* register.php - where are
    you saving it? If you're saving it somewhere else you'll want to adjust the
    name of the script your form is POSTing to as well.

  • Thanks for the guideline of creating browsergame. I was looking for it. I have successfully followed the first six steps. But I couldn’t create the INSERT query. I have checked the code several times. I have exactly follow what you have written. But it just didn’t work. Can you please help me to find out the error?

  • Sondar

    Here is a picture of what The PHP Admin screen looks like.

    http://yfrog.com/5sphpadminp

    I clicked on User Priviliges so thats why its Orange (I think).

  • Sondar

    I don't understand where I shoulkd input the SQl you have posted. I signed up to a free package with PHP My Admin support and thats all set up but i dont know where to input what you have posted.

    Please Help

  • Gradient

    Warning: mysql_fetch_row(): supplied argument is not a valid MySQL result resource in /home/a8891953/public_html/register.php on line 15

    That is what I get when trying to register.

  • If you're getting that error, it means that something is wrong with your
    connection to MySQL - double check the values that you passed to
    mysql_connect.

  • BUnzaga

    Actually I found out I was wrong, delete if you can.

  • Hi John, and thanks for the tips!

    I wasn't aware that md5's were vulnerable to rainbow tables - thanks for pointing that out. I'll be sure to write a follow-up post as soon as possible clearing up why you should be doing more than just md5ing your data.

  • JohnMunsch

    The MD5 hash doesn't actually protect you if someone were able to dump your table of users or gain access to the database in some fashion.

    That's because there exist large hash dictionaries available to hackers which have every word in the dictionary and all common names already pre-hashed using common hashes like MD5. The hacker can search through the list of hashed user passwords for matches in the hash dictionary and then consult the dictionary whenever there is a match to see what word or name was used as the original (unhashed) password. It won't allow them access to accounts where people used strong passwords, but think how many people use the name of a spouse or a common word as a password.

    That's why you usually use MD5 in combination with a random "salt" value. You take the user's password (e.g. porcupine), you prepend a randomly generated number or string (e.g. 352) and then MD5 hash that (e.g. 352porcupine => 'alaskdf5...') saving both the randomly generated number and the hash. Then whenever the user submits a password you again prepend the same salt value in front of it and see if it hashes to the same value again. The random value in front of each and every password stored then makes the hash dictionary useless.

  • Graham

    use SHA1 instead of MD5. Event with Salts, MD5 is still vulnerable to collision attacks, and should not be used for security purposes.

  • Thanks for the heads-up, Graham!

blog comments powered by Disqus

About

Building Browsergames is a blog about browsergames(also known as PBBG's). It's geared towards the beginner to intermediate developer who has an interest in building their own browsergame.

Sponsors

Got Something to Say?

Send an e-mail to luke@buildingbrowsergames.com, or get in touch through Twitter at http://twitter.com/bbrowsergames