How To: Code Your First Web App (Part 1)

December 27, 2006 · 39 comments

In its most basic form, a web application is typically comprised of multiple files utilizing PHP and MySQL technologies on a LAMP server. PHP provides a powerful means of carrying out your web application’s functions by way of server-side scripting while MySQL is used to store information in a database. In this series of posts I will be showing you how easy it is to create a simple web application framework which you can adapt for almost any purpose – all this with only basic PHP and MySQL knowledge.

The following files will be available as a download in the next part, so don’t worry about copying and pasting everything.

Planning & Database Design

Before you start creating your web application you need to figure out what your web application will be doing and what types of things will need to be stored in the database. I will be showing you how to handle user accounts in this how to.

You will have one table dedicated to storing user information; things like user name, password, email, session and user id. Depending on what your web application will do you might have more user-related fields. My party finder web application had additional fields for age, city and state. Then you might have another database table for other types of data stored on your web app – if your web app manages events you would probably have a table for events including fields like date, time, street, zip code, city, state, venue name, etcetera.

I’ll leave the design of other database tables up to you so I’ll continue with setting up a database and table for users. If you want to learn more about database design, take a look at this great article. Here’s what I want to create so far: a database with a “users” table containing the fields “user”, “password”, “email”, “session” and “id”. The user id can be used later on for making specific MySQL queries on users since I will setup the id to automatically increment with each new user. Setting up auto-incrementing indexes is also just good programming practice.

Assuming you have phpMyAdmin installed on your server, go to the homepage for your phpMyAdmin install and create a new database named “webapp”. For those lacking phpMyAdmin, you can simply run the following code once logged into MySQL.

create database webapp;

Create the “users” table by selecting the newly created database “webapp” in phpMyAdmin and finding the “Create new table on database webapp” text at the bottom. Type in “users” for the name of the table as well as “5″ for the number of fields. I recommend using phpMyAdmin for the next part – filling out the details for each of the 5 fields.

Webapp Database new table

The next hurdle to overcome regards which data types and attributes to set each field in our users table. The id for each of the users in the table should be an int(7) – an integer with room for 7 digit values. Unless you are expecting to have more than a million users you’ll want to keep that value as small as possible. The same goes for most data types for table fields – keep them as small as possible to reduce overhead and increase speed. Cal Henderson of Flickr explains this concept in great detail in his book Building Scalable Web Sites.

The other fields we have – user, password, email and session, will all be of the type “varchar” but might have varying lengths. For email addresses and user names, I think 32 is long enough for typical user names/email addresses. That would be varchar(32). The sessions field will also be varchar(32) due to the way I will setup PHP sessions. Finally, the password field will be set to varchar(32) since I will implement MD5 encryption before each password is stored or changed.

CREATE TABLE `users` (
`id` INT( 7 ) NOT NULL AUTO_INCREMENT ,
`user` VARCHAR( 32 ) NULL ,
`password` VARCHAR( 32 ) NULL ,
`email` VARCHAR( 32 ) NULL ,
`session` VARCHAR( 32 ) NULL ,
INDEX ( `id` )
) TYPE = MYISAM ;
Webapp Database users table
Overview of the users table in phpMyAdmin

Connecting to the Database

Before I begin with the PHP functions for creating and accessing user information, I need to write a few lines of PHP to connect to the MySQL database. In a file called “util.php” I have written the following lines:

[code lang="PHP"]
< ?php
if( !defined('IN_PHP') )
{
die("hacking attempt");
}

$mysql_host = "localhost";
$mysql_user = "root"; // YOUR USERNAME
$mysql_pass = "root"; // YOUR PASSWORD
$mysql_db = webapp;
?>
[/code]

The file will be loaded with each file in the web application requiring access to the database. The first few lines at the top are a minor precaution to ensure that no one can directly view this file and thus steal your database info. In all other web app PHP files I will define “IN_PHP”, allowing util.php to be accessed.

Now to actually connect to the database, I have a simple function in a new file called “functions.php” that will also be included in each web app file requiring database connectivity. This function is called xmysql_connect() since there is already a PHP function named mysql_connect(). This file also has the lines for that “IN_PHP” thing for basic security.

[code lang="PHP"]< ?php
if( !defined('IN_PHP') )
{
die("hacking attempt");
}
function xmysql_connect()
{
global $mysql_host, $mysql_user, $mysql_pass, $mysql_db;
@mysql_connect($msql_host, $mysql_user, $mysql_pass) or die('Could not connect to database: ' . mysql_error());
mysql_select_db($mysql_db) or die('Could not select database: ' . mysql_error());
}
?>[/code]

When xmysql_connect() is run in other web app files that include util.php, functions.php and define “IN_PHP”, a successful connection to the database is made. You can see how it accesses the database information from util.php. One thing you will quickly learn about PHP is that you must declare variables as global before they can be read within a function.

Wherever you see die(), that outputs a statement when the action it is OR’d with fails. For example, if I forgot to specify a database name, mysql_select_db() wouldn’t be able to run and would output “Could not select database: ” and then concatenate (that’s what the dot does) the mysql error. Outputting errors like this is good practice and helpful when it comes time to debug.

How ’bout Them Users?

To manage user accounts, there are several necessary functions I have included in the functions.php file. The first function below, create_user(), takes three parameters and feeds them into the database to create a new user. If your web application keeps track of more than just user name, password and email, you will have to edit this function to accommodate for the extra parameters.

The next function, user_exists(), does as it implies and checks to see if a user by the name $user already exists in the database. This is used later on when making new users. Meanwhile, get_user() polls the database to get the current, logged in user’s information – based on the session. Finally, do_login() and do_logout() do exactly what you think while make_safe() is a very handy function given to me by Josh Pigford that is heavily used later on to ensure that the site is not vulnerable from mischievous data entry (it prevents things like XSS in forms). This is inline with data input validation for forms. There’s a fantastic article that goes in-depth about various methods of data validation (things like validating phone numbers, etc) in the O’Reilly book Web Database Applications with PHP & MySQL.

[code lang="PHP"]
function create_user($user, $password, $email) {
$encpwd = md5($password);
$query = "insert into users set user='$user', password='$encpwd', email='$email'";
$result = mysql_query($query);
}

function user_exists($user) {
$query = "select user from users where user='$user'";
$result = mysql_query($query);
if($result == NULL)
return false;
$line = mysql_fetch_array($result, MYSQL_ASSOC);
mysql_free_result($result);
return $line !== FALSE;
}

function get_user() {
$query = "select user from users where session='".session_id()."'";
$result = mysql_query($query);
if($result == NULL)
return NULL;
$line = mysql_fetch_array($result, MYSQL_ASSOC);
mysql_free_result($result);
if($line === FALSE)
return NULL;
return $line['user'];
}

function do_login($user, $password) {
$encpwd = md5($password); //encrypt password with MD5!
$query = "select user, password from users where user='$user'";
$result = mysql_query($query);
if($result == NULL)
return false;
$line = mysql_fetch_array($result, MYSQL_ASSOC);
mysql_free_result($result);
if( $line['password'] !== $encpwd )
return false;
$query = "update users set session='".session_id()."' where user='$user'";
$result = mysql_query($query);
return true;
}

function do_logout($user) {
$query = "update users set session='' where user='$user'";
//that clears the session
$result = mysql_query($query);
}

function make_safe($variable) {
$variable = htmlentities($variable, ENT_QUOTES);
if (get_magic_quotes_gpc()) {
$variable = stripslashes($variable);
}
$variable = mysql_real_escape_string(trim($variable));
$variable = strip_tags($variable);
return $variable;
}
[/code]

These functions finish off my functions.php file so now I can begin to concentrate on the main PHP file and forms.

The Basic Framework

Now that I have most of the vital functions taken care of, it’s time to start coding the index.php file. Every new file will pretty much require a few includes and commands so creating a header.php file that will be included in each file is an excellent idea. My header.php file is composed of the following lines:

[code lang="PHP"]< ?php
define('IN_PHP', true);
//very very basic security
include('util.php');
include('functions.php');
session_start();
xmysql_connect();

//these next lines are optional
//they provide unique page titles
$url = $_SERVER['REQUEST_URI'];
$pages = Array(
"/about.php" => "» About",
"/blah.php" => "» Blah",
"/blah2.php" => "» Blah 2"
);
$title = $pages[$url];
?>
< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">< html xmlns="http://www.w3.org/1999/xhtml">



[/code]

First, I defined my basic security precaution of the “IN_PHP” phrase that util.php and functions.php look for, then I included those two files. After that, session_start() is called to initialize the user session. Finally, the xmysql_connect() function from functions.php is executed. There is now an active connection to the database.

The next PHP lines are a nifty way to dynamically alter page title names depending on what page the user is on. You have to manually input the pages and their accompanying page titles in the $pages array. The code grabs the current page requsted by the user with REQUEST_URI, looks in the array and snags the appropriate title. Since the page title is later declared as “My First Web App” and then a PHP echo of $title, the full title for the hypothetical about.php would be “My First Web App » About”.

The header file also links to a CSS file but I won’t be covering any CSS or styling in this series of posts. The header file where you load other javascript files your web app might utilize or things like setting an API key if your web app makes uses Google Maps.

This is getting a bit long so I’ll be splitting it up into parts. Tune in for the next segment hopefully tomorrow. You might find it easier to just grab my RSS feed. Part 2 and Part 3 have been published.

PaulStamatiou.com runs on the Thesis Theme for WordPress

How smart is your Theme?  How good is your support? Check out ThesisTheme for WordPress.

Thesis is the search engine optimized WordPress theme of choice for serious online publishers. If you’re a blogger who doesn’t understand a lot of PHP, Thesis will give a ton of functionality without having to alter any code. For the advanced, Thesis has incredible customization possibilities via Thesis hooks.

With so many design options, you can use the template over and over and never have it look like the same site. The theme is robust and flexible enough not only to accommodate a site like PaulStamatiou.com, but also to enable the site to run far more efficiently than it ever has before.

SEO Copywriting Made Simple
I used the Scribe WordPress plugin and service to optimize this blog post for SEO.

{ 10 trackbacks }

How To: Code Your First Web App | Open Switch
December 27, 2006 at 10:13 am
Working With Web Apps - MuhammadK.com
December 27, 2006 at 12:18 pm
Web Application Development For Beginners » Interweb World
December 29, 2006 at 4:06 pm
agyampark · links for 2007-01-01
December 31, 2006 at 8:28 pm
Learn PHP « Online Diary
January 2, 2007 at 3:26 pm
RL » Blog Archive » I’m Back!
January 3, 2007 at 11:56 am
PHP tutorials for beginners « Junal on the run
December 24, 2007 at 8:03 am
Web development | Web Design & Development
September 21, 2008 at 6:20 pm
How I Learned to Code - PaulStamatiou.com
October 6, 2008 at 5:05 pm
Web development | Teleactivities
April 21, 2009 at 6:29 am

{ 29 comments… read them below or add one }

1 josue salazar December 27, 2006 at 4:09 am

Great post!

Reply

2 Muhammad K December 27, 2006 at 4:19 am

Waiting for the next one!

Reply

3 Adam Teece December 27, 2006 at 4:19 am

Wow, amazing beginning to what I am sure will be an awesome series.

Reply

4 Michael December 27, 2006 at 4:24 am

Hey everybody! One word: Django. Go check it out, don’t even bother with PHP.

http://www.djangoproject.org

Reply

5 Paul Stamatiou December 27, 2006 at 4:26 am

Where’s the fun in pre-made web app frameworks? :-P Besides, don’t cha love saying “yup… I built it from scratch”

Reply

6 pankajkala December 27, 2006 at 4:38 am

gr8 post

Reply

7 Hugo December 27, 2006 at 5:56 am

Congratulations.
Great post. I can’t wait for the rest.

Reply

8 quaisii December 27, 2006 at 7:30 am

This is something I’ve always wanted to know how to do

Reply

9 Soroush December 27, 2006 at 10:10 am

Thanks Paul! There were some little things in there, that I found useful! Looking forward to part two! ;)
Oh, and regarding using a framework, I guess it’ll become useful once you do these sort of things over and over. Then you’d want a framework to make it all easier. I guess!

Reply

10 Frank 'viperteq' Young December 27, 2006 at 10:55 am

Paul, this is an awesome post. I think this series will shape up to be the best articles yet. You’ve just helped me kickstart my own project….thank you!!!!

Reply

11 Amit Goyal December 27, 2006 at 11:55 am

Great post and leads up to what I expect to be a great series!! Keep them coming. Also you could create a PDF of these.

Can I also request for a series on WSDL using LAMP?

Reply

12 Nick December 27, 2006 at 12:29 pm

When I pasted the following line in my php editor, it produced a syntax error.

$query = “update users set session=’’ where user=’$user’”;

I found the error to be the quote marks after session=

I changed them to match like this session=”

Is this right?

Reply

13 Nick December 27, 2006 at 12:33 pm

And I see that when I posted my message the quotes got swapped around . So, that now the error would appear in my change. Probably something to do with the blog software. See Paul’s code in functions.php for the differences to what I posted

I guess really it doesn’t matter as long as they are the same.

Reply

14 Trey Copeland December 27, 2006 at 12:37 pm

nice tutorial.

Reply

15 PHP MySQL Web Hosting December 27, 2006 at 1:31 pm

Great post indeed,well set for the begginners.

Reply

16 Kory Twaites December 27, 2006 at 2:24 pm

I can’t imagine you doing the whole thing like you originally said. Like others have said, great article. And this will be useful in a few little things I’m trying to develop.

Reply

17 Paul Stamatiou December 27, 2006 at 3:58 pm

@Nick – yeah the quotes thing is always a problem with posting code on my blog. This is why I’ll be including the files in a download at then end of the last part.

Reply

18 Ryan Powell December 27, 2006 at 6:36 pm

Finally, I’ve been waiting for this! I just started developing a website for a career fair at my school, and now I can work on the users portion!

Thanks and looking forward to the rest!

Reply

19 Chuck Cheeze December 28, 2006 at 11:20 am

Very cool. As an ASP to PHP convert, this is a great article to take me up a step in my skills. What else I would like to see, if its not already going to be in part 2, is a discussion about how you setup a template for your entire site. I am just leaving Dreamweaver (code view!) for Textmate/Transmit (now that I found out how to auto upload files on save from Textmate using Transmit) and the one thing I still loved about DW was creating a template and then easily creating new pages from that template. Thanks.

Reply

20 Dan Theade January 8, 2007 at 8:29 pm

Working on building my first web app using OpenLaszlo, would love to hear your opinion on their platform.

Reply

21 Mojtaba January 22, 2007 at 6:37 am

Hi Paul,
Nowadays,I have been studing in PHP4 & Mysql. Would you support me more a little knowledge about E-mail(with attachment) and discussion board applications.

Thanks…
Mojtaba A.Ibrahim
abolidha@yahoo.com

Reply

22 Mojtaba January 23, 2007 at 6:31 am

hi Paul Stamatiou,
This message appeared when clicking on the menu (manage Contacts):
“Warning: Cannot modify header information – headers already sent by
(output started at C:\webapp\header.php:23) in C:\webapp\manage.php on line9″

When the webapp loaded,The menus boxes showed about 20px above the body of the white page. of course not as shown on your example interface(well fitted at the edge in between the semi blue header and the white page body).

Reply

23 Paul Stamatiou January 23, 2007 at 11:24 am

@Mojtaba – hey, it must be some small issue with the way it’s setup on your system or something, as I don’t get that here. how do you have it setup?

Reply

24 Tony Y. March 8, 2007 at 3:54 pm

Nice tutorial! Keep it coming. Reader will benefit this.

But if you are still not confident you can do this, go to Nenest (http://www.nenest.com), which enables you build database-driven web application without a single line code. All you need to do is just write Word like documents. Also you are able to import existing database on the fly.

Reply

25 Akhil September 7, 2007 at 11:29 am

Hey guys Can any one please tell me what make_safe() function does?????

i will appreciate your answer

Reply

26 Paul Stamatiou September 24, 2007 at 4:32 pm

make_safe() makes the input.. safe and returns it. ;-) That is, you should never trust input from a user and this sanitizes it from possible exploits. Just a little precaution.

Reply

27 Akhil November 14, 2007 at 4:51 pm

Paul, I have followed your tutorial..and reached to a point to make my own website. Now my next step is to further exploit the web applications.Can you please recommend me the good books those deal with some applications? I am currently building my new application as in Video gallery with shopping cart facility. I did a lot but again sucks in ideas.I am keen in OO paradigm of php and want to make CMS .Your effort will be appreciated as before. You are a star.

XXXX
Akhil

Reply

28 Akhil November 22, 2007 at 5:37 pm

Hello Paul,

How are you? Paul,it’s funny though but really a useful question for me? Can you please tell me how to synchronize file system with database. say for example i store images in the image folder and a path of that particular image in the database. When i delete that particular path from database , must delete image in the folder. I will appreciate your effort.

Regards
Akhil

Reply

29 Jehzeel Laurente February 23, 2009 at 9:47 pm

aha.. a great tut for noobs like me :D I just subscribed in your RSS feeds. Btw, what plugin are you using in the number of comments when I hover the name of the commenter? I’m just curious. Did you built it from scratch? or was it a wp plugin and I just really don’t know what’s the name of the specific plugin? :(

Hoping for your reply…

Reply

Leave a Comment

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Previous post:

Next post: