Building Browsergames: Putting it all together (PHP)

So, we’ve built a simple registration page, and a simple login page. Now it’s time to tie it all together, so that we can use the things we’ve been working on in our game.

First off, we’re not going to require users to validate their e-mail addresses. This is a decision that’s really up to you – but for the sake of this tutorial, users won’t need to validate their e-mail. If you want to make them verify it, you can always use the e-mail confirmation system we walked you through building earlier.

But before we start writing any code, we’re going to need a database structure to work with. We’ll just work off of the structure we set up in the other tutorials:

CREATE TABLE users (
	id int NOT NULL AUTO_INCREMENT,
	username varchar(250),
	password varchar(50),
	is_admin tinyint(1) DEFAULT 0,
	PRIMARY KEY(id)
);
CREATE TABLE stats (
	id int NOT NULL AUTO_INCREMENT,
	display_name text,
	short_name varchar(10),
	PRIMARY KEY(id)
);
INSERT INTO stats(display_name,short_name) VALUES ('Magic','mag');
INSERT INTO stats(display_name,short_name) VALUES ('Attack','atk');
INSERT INTO stats(display_name,short_name) VALUES ('Defence','def');
CREATE TABLE user_stats (
	id int NOT NULL AUTO_INCREMENT,
	user_id int,
	stat_id int,
	value text,
	PRIMARY KEY(id)
);

On the code side, we’ll start with making our registration page from earlier and make it auto-focus, remember the values sent to it, and use Smarty. This is what the Smarty template for our registration page will look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
	<html>
	<head>
		<title>Register</title>
	</head>
	<body>
		{if $error ne ""}
			<span style='color:red'>Error: {$error}</span>
		{/if}
		{if $message ne ""}
			<span style='color:green'>{$message}</span>
		{/if}
		<form method='post' action='register.php'>
			Username: <input type='text' name='username' id='username' value='{$smarty.post.username}' /><br />
			Password: <input type='password' name='password' /><br />
			Confirm Password: <input type='password' name='confirm' /><br />
			<input type='submit' value='Register!' />
		</form>
		<script type='text/javascript'>
		document.getElementById('username').focus();
		</script>
	</body>
	</html>

We used a conditional statement to make sure that our error and success messages only display when there is actually something to display – but other than that, you’ve seen all of this before. Save that file as register.tpl, and put it into your smarty templates directory that we set up earlier.

The next thing we need to build is the actual registration page that uses the Smarty template. It’s pretty easy to just modify our other registration code to work with Smarty:

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
38
39
40
41
<?php
 
// put full path to Smarty.class.php
require('/usr/local/lib/php/Smarty/Smarty.class.php');
$smarty = new Smarty();
 
$smarty->template_dir = '/web/www.domain.com/smarty/templates';
$smarty->compile_dir = '/web/www.domain.com/smarty/templates_c';
$smarty->cache_dir = '/web/www.domain.com/smarty/cache';
$smarty->config_dir = '/web/www.domain.com/smarty/configs';
 
if($_POST) {
	$password = $_POST['password'];
	$confirm = $_POST['confirm'];
	if($password != $confirm) {
		$error = 'Passwords do not match!';	
	} else {
		require_once 'config.php';		// our database settings
		$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) { 
			$error = 'that username is taken.';
		} 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);			
			$message = 'Congratulations, you registered successfully!';
		}
	}	
}
$smarty->assign('error',$error);
$smarty->assign('message',$message);
$smarty->display('bb-register.tpl');
 
?>

And that’s our registration form, using Smarty. But we still don’t quite have any stats set up for the user – and they’re going to need some stats. Let’s take our flexible stats code from earlier, and bake it into our code. To begin with, we’ll start off with the basic stats code from before, and just add the fact that whenever a stat is requested that doesn’t exist, it creates a new row in the database for that stat for the user, and sets the stat’s value to 0:

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
38
39
40
function getStat($statName,$userID) {
	require_once 'config.php';
	$conn = mysql_connect($dbhost,$dbuser,$dbpass)
		or die ('Error connecting to mysql');
	mysql_select_db($dbname);
	$query = sprintf("SELECT count(value) FROM user_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = '%s' OR short_name = '%s') AND user_id = '%s'",
		mysql_real_escape_string($statName),
		mysql_real_escape_string($statName),
		mysql_real_escape_string($userID));
	$result = mysql_query($query);
	list($count) = mysql_fetch_row($result);
	if($count == 0) {
		// the stat doesn't exist; insert it into the database
		$query = sprintf("INSERT INTO user_stats(stat_id,user_id,value) VALUES ((SELECT id FROM stats WHERE display_name = '%s' OR short_name = '%s'),'%s','%s')",
		mysql_real_escape_string($statName),
		mysql_real_escape_string($statName),
		mysql_real_escape_string($userID),
		'0');
		mysql_query($query);
	}
	$query = sprintf("SELECT value FROM user_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = '%s' OR short_name = '%s') AND user_id = '%s'",
		mysql_real_escape_string($statName),
		mysql_real_escape_string($statName),
		mysql_real_escape_string($userID));
	$result = mysql_query($query);
	list($value) = mysql_fetch_row($result);
	return $value;		
}
function setStat($statName,$userID,$value) {
	require_once 'config.php';
	$conn = mysql_connect($dbhost,$dbuser,$dbpass)
		or die ('Error connecting to mysql');
	mysql_select_db($dbname);
	$query = sprintf("UPDATE user_stats SET value = '%s' WHERE stat_id = (SELECT id FROM stats WHERE display_name = '%s' OR short_name = '%s') AND user_id = '%s'",
		mysql_real_escape_string($value),
		mysql_real_escape_string($statName),
		mysql_real_escape_string($statName),
		mysql_real_escape_string($userID));
	$result = mysql_query($query);
}

At this point, we’ve set up our database structure, created our registration page, and set up the stats code so that we can retrieve a user’s stats after they’ve logged in. But we still don’t have a login page! We’ll start off by creating another Smarty template, called login.tpl:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
	<html>
	<head>
		<title>Login</title>
	</head>
	<body>
		{if $error ne ""}
			<span style='color:red'>Error: {$error}</span>
		{/if}
		<form action='login.php' method='post'>
			Username: <input type='text' name='username' id='username' value='{$smarty.post.username}' /><br />
			Password: <input type='password' name='password' /><br />
			<input type='submit' value='Login' />
		</form>	
		<script type='text/javascript'>
		document.getElementById('username').focus();
		</script>
	</body>
	</html>

Next, we’ll modify our login page to use Smarty and the template we just built:

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
38
39
40
41
42
43
44
45
46
47
48
49
<?php
 
// put full path to Smarty.class.php
require('/usr/local/lib/php/Smarty/Smarty.class.php');
$smarty = new Smarty();
 
$smarty->template_dir = '/web/www.domain.com/smarty/templates';
$smarty->compile_dir = '/web/www.domain.com/smarty/templates_c';
$smarty->cache_dir = '/web/www.domain.com/smarty/cache';
$smarty->config_dir = '/web/www.domain.com/smarty/configs';
 
session_start();
if($_POST) {
	require_once 'config.php';
	$username = $_POST['username'];
	$password = $_POST['password'];		
	$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') AND password='%s'",
		mysql_real_escape_string($username),
		mysql_real_escape_string(md5($password)));
	$result = mysql_query($query);
	list($count) = mysql_fetch_row($result);
	if($count == 1) {
		$_SESSION['authenticated'] = true;
		$_SESSION['username'] = $username;
		$query = sprintf("UPDATE users SET last_login = NOW() WHERE UPPER(username) = UPPER('%s') AND password = '%s'",
			mysql_real_escape_string($username),
			mysql_real_escape_string(md5($password)));
		mysql_query($query);
		$query = sprintf("SELECT is_admin FROM users WHERE UPPER(username) = UPPER('%s') AND password='%s'",
			mysql_real_escape_string($username),
			mysql_real_escape_string(md5($password)));
		$result = mysql_query($query);
		list($is_admin) = mysql_fetch_row($result);
		if($is_admin == 1) {
			header('Location:admin.php');			
		} else {
			header('Location:index.php');				
		}
	} else {	
		$error = 'There is no username/password combination like that in the database.';
	}
}
 
$smarty->assign('error',$error);
$smarty->display('bb-login.tpl');
?>

And finally, we’ll add an ultra-basic index page – for now, it will just show the user their current username, and give them a link to log out. Here’s what the template will look like – save it as index.tpl:

1
2
3
4
5
6
7
8
9
	<html>
	<head>
		<title>Index Page</title>
	</head>
	<body>
		<p>Hello, {$name}!</p>
		<p><a href='logout.php'>Logout</a></p>
	</body>
	</html>

And here’s the code behind our ultra-simple index page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
 
// put full path to Smarty.class.php
require('/usr/local/lib/php/Smarty/Smarty.class.php');
$smarty = new Smarty();
 
$smarty->template_dir = '/web/www.domain.com/smarty/templates';
$smarty->compile_dir = '/web/www.domain.com/smarty/templates_c';
$smarty->cache_dir = '/web/www.domain.com/smarty/cache';
$smarty->config_dir = '/web/www.domain.com/smarty/configs';
 
session_start();
$smarty->assign('name', $_SESSION['username']);
$smarty->display('index.tpl');
 
?>

And, to put the icing on the cake, let’s add our logout page. It’s pretty simple:

1
2
3
4
5
6
7
8
9
<?php
session_start();
$_SESSION = array();
if (isset($_COOKIE[session_name()])) {
    setcookie(session_name(), '', time()-42000, '/');
}
session_destroy();
header('Location:http://google.com');
?>

All it does is clear all the session data, remove the cookie being used to track the session, and then redirect the user to http://google.com – although you could redirect them to whatever page you wanted to(Wordpress, for example, redirects to the login page with ?logged_out=true, displaying a little ‘hey, you logged out!’ message.).

And that’s all there is to the beginnings of our game! Now users can register, log in, see their username on the index page, and log out. It might not seem like much, but it’s the basic framework that every game needs – including yours.

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.

Friday, May 30th, 2008 buildingbrowsergames, code, gettingstarted, php, tutorial
  • Siem Wigger

    i can't say how much practise your articles gave me.

  • Patrick

    where do I save the function getstat stuff?

  • Red

    Well I got an extra space in my script its line 24 here. In my script line 25 is
    list($count) = mysql_fetch_row($result); I am not sure what is causing the error everything matches.

  • MrAngel

    for some reason my page goes white and nothing happes

  • a`a

    no it puts ur session into an array

  • MrLollige

    What does
    $_SESSION = array();
    do? Does it empty the session array?

  • bam! and the dirt is gone

    i just cant get it to work i use free web hosting

  • I would recommend that you try contacting your web host's support team, and
    checking to see if they can install Smarty for you. If they can't, you can
    download the entire Smarty library and put it on the server yourself - you
    would then just need to change the paths in your code to refer to the local
    copy of Smarty(because the installed version wouldn't exist).

  • bam! and the dirt is gone

    what about all us country folk that dont have, use smartY!!! lol thanks
    ps dont reply to the invalid email

  • If you're not using Smarty, I would highly recommend that you look into it,
    and fast - I don't think I've worked on a single PHP project that hasn't
    become large and unwieldy without some sort of template engine to keep the
    code and display logic separated.

  • Hi Rich,

    I'm glad you like it! My goal has always been to try and keep these posts as easy to follow as possible, and I'm glad you feel that way about this one.

  • Very nicely laid out and easy to follow. Thanks! Just ran across this site and am looking forward to following it as you move on to new topics.

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