Create a Portfolio Client Area Using PHP and MySQL: Part 3

This tutorial finally gets into the inside area for the client’s area. We’ll create the login form, discuss sessions in PHP, create a profile page and area for the client, and finally, create a logout script.

Read up on the other parts of the tutorial below:

Login Form

The login form is going to be very similar to our signup form, in that it is a basic HTML form, leading to a PHP script that we’ll call login.php. What’s different about a login script though, is that instead of inserting data into a database, we’re going to be calling data from the database and saving the user’s data until we don’t need it anymore (when the client logs out.).

To keep things simple at first, let’s just create the HTML login form, naming it loginform.html.

Login Form

<form action="login.php" method="post">

        Username:
	<input type="text" name="username" /><br />

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

	<input type="submit" value="Submit" />

</form>

Note that the password field is hidden by giving it the type “password,” we’re using the post method, and sending the form to login.php. If anything is unclear, head on over to the first tutorial for an explanation via the signup form.

Login Script – Login.php

Note: I’ve made a major error from the first tutorial that I didn’t realize at the time until I had to deal with it again for this tutorial. Realizing these sorts of errors is an essential part of the programming process.

I had limited the password field in our database to 20 characters — which seems reasonable at first. However, as we know, we used md5 encryption to insert password into our database in the second tutorial. Md5 uses 32 characters for the password, no matter the original length of the password. So when trying to compare a given password in the login form and the encrypted password in the database, the didn’t match because one was 32 characters and the other was only 20.

To fix this, let’s change the field length in our database to 32 characters in our password field:

  1. Go to our database in phpMyAdmin, and click on our table (clients)
  2. In the top tabs, to go Structure
  3. In the password field, go to edit (the pencil icon on the right)
  4. Change the Length/Values to 32 (instead of 20)

Correction

Also, note that when testing, we must create a new username and password sample because the old password will still be in the database as 20 characters.

Now for the login PHP script itself. Here’s basically what needs to happen in plain English:

  1. The client will use the login form and the form will redirect the information to login.php
  2. The script will find the data where the given username and password match
  3. If it matches, there will be data we can work with and we can create a session. Otherwise, we will tell the user the username and password didnt match.
  4. The client will be redirected to the profile page, which will be pre-populated with their information that is found from the session that was created

So let’s start by opening up a new document and creating our login.php page. Below we begin our PHP tags, and connect to the database.

< ?php

// Connect to the database
require('db.php');

Simple enough, right? To get organized, let’s create a username and password variables within our login.php. Since we used the “post” method in our login form, we already have their values in the predefined $_POST variable. We can save them to custom variables below:

// Set username and password variables for this script
$user = mysql_real_escape_string($_POST["username"]);
$pass = mysql_real_escape_string(md5($_POST["password"]));

Remember that the parameter of the $_POST array ($_POST["parameter"]) depends on the “name” attribute from our login HTML form. We used md5 again in this password variable, because we’ll need to compare the encrypted password in the database to this encrypted version above. Otherwise, they would not match even if the user entered in the correct password. Also, notice mysql_real_escape_string() for the prevention of SQL injection attacks.

Next we’re going to use these new variables to select the data where these two variables match — the username and password that is. If the username and password match, it will enter the data into $clientdata, otherwise it will insert nothing. An error will only run if we have an incorrect syntax with our query, in which we can fix before our client area goes live.

// Make sure the username and password match, selecting all the client's
// data from the database if it does. Store the data into $clientdata
$clientdata = mysql_query("SELECT * FROM clients WHERE username='$user' and password='$pass'")
     or die (mysql_error());

Next, we’ll have to put our query placed into $clientdata into an array we can work with. Simply done, we can use the function below:

// Put the $clientdata query into an array we can work with
$data = mysql_fetch_array($clientdata, MYSQL_ASSOC);

It’s pretty straightforward and a commonly used snippet — but feel free to ask questions or research this function further for more detail.

We’re just going to spit out the rest of the code here because it is in one big if/else statment block. I’d like to place it together to avoid confusion.

Look over the comments within the script for further explanation.

// If the username and password matched, we should have 1 entry in our
// $clientdata array. The function mysql_num_rows() can count this.
// If not, we should have 0. So, we can use a simple if/else statement
// to determine if they matched up.

// If there is 1 row in the query, it is our user's row
if(mysql_num_rows($clientdata) == 1){
	// Start a new blank session. This will assign the user's server
	// with a session with an individual ID
	session_start();

	// With our session started, we can assign variables for a logged
	// in user to use until they log out.
	$_SESSION['username'] = $user;
	$_SESSION['email'] = $data['email'];
	$_SESSION['paypal'] = $data['paypal'];

	// Then, redirect them to the profile page
	header('Location: profile.php');

// Otherwise, we did not get anything entered into our query, meaning
// the username and password did not match.
}else{echo "The username and password don't match. Please go back and try again.
            (Or you could redirect them to the login page again.)";}

For your convenience, the entire script is below.

<?php 

// Connect to the database
require('db.php'); 

// Set username and password variables for this script
$user = mysql_real_escape_string($_POST["username"]);
$pass = mysql_real_escape_string(md5($_POST["password"])); 

// Make sure the username and password match, selecting all the client's
// data from the database if it does. Store the data into $clientdata
$clientdata = mysql_query("SELECT * FROM clients WHERE username='$user' and password='$pass'")
 or die (mysql_error());

// Put the $clientdata query into an array we can work with
$data = mysql_fetch_array($clientdata, MYSQL_ASSOC);

// If the username and password matched, we should have one entry in our
// $clientdata array. If not, we should have 0. So, we can use a simple
// if/else statement
if(mysql_num_rows($clientdata) == 1){
	// Start a new blank session. This will assign the user's server
	// with a session with an idividual ID
	session_start();

	// With our session started, we can assign variables for a logged
	// in user to use until they log out.
	$_SESSION['username'] = $user;
	$_SESSION['email'] = $data['email'];
	$_SESSION['paypal'] = $data['paypal'];

	// Then, redirect them to the profile page
	header('Location: profile.php');
}else{echo "The username and password don't match. Please go back and try again.
            (Or you could redirect them to the login page again.)";}

If we test it out, we see we are redirected to a 404 not found page. This means the script has gone through and worked without errors, because it has brought us to our profile.php page, which has not yet been created.

Profile Page

Once we understand what a session is, one can see how easy it is to create a profile page. If we’re on the profile page, we can first check to see if the user is logged in. If they are, we’ll show their profile by determining who they are from the session variables, which calls them from the database. If the are not logged in, we direct them away from the protected page.

This page will be a mix of HTML and PHP, as we need to display HTML headers, paragraphs, and other design elements, but also have access to the session and it’s variables to interact with the client. Create a new page called profile.php.

We’ll have to start the session. We must do this for any page that we wish to access the user’s data from. It is specific to the users’ server session ID.

// We have to start our session every time we're
// going to call our session variable for a
// logged in issue.
session_start();

Next, let’s make sure the user is logged in by checking if the $_SESSION array is set. This will work because we define the session variables within our login.php page. Specifically, we need to call one of the session variables. We’ll use the username variable.

<?php

// Let's also make sure the user is logged in at all
// If the PHP $_SESSION['username'] variable is not (!) set
if(!isset($_SESSION['username'])){
    //Then redirect them to the login page
    header( 'Location: loginform.html' );
}

// Otherwise, we continue to show the profile page.

Let’s add some basic headers and such, then call for the username and apply it in a practical sense.

echo "<h1>Profile Page</h1>";

echo "<p>Welcome, " . $_SESSION['username'] . "!
          This is your profile page. You can view and edit
          your information, or navigate to any of the other
          options.</p>";

echo "Your email address: " . $_SESSION['email'] .  "<br />" .
        "Your PayPal address: " . $_SESSION['paypal'];

This page is easy enough, and we can see how adding other types of data to the database can be used in this page as well. Hopefully this sort of profile page is easily customizable to your own needs. Below is the entire page:

<?php

// We have to start our session every time we're
// going to call our session variable for a
// logged in issue.
session_start();

// Let's also make sure the user is logged in at all
// If the PHP $_SESSION[] array is not (!) set
if(!isset($_SESSION['username'])){
    //Then redirect them to the login page
    header( 'Location: loginform.html' );
}

echo "<h1>Profile Page</h1>";

echo "<p>Welcome, " . $_SESSION['username'] . "!
          This is your profile page. You can view and edit
          your information, or navigate to any of the other
          options.</p>";

echo "Your email address: " . $_SESSION['email'] .  "<br />" .
        "Your PayPal address: " . $_SESSION['paypal'];

echo "<p><a href='logout.php'>Logout</a></p>";

Logout

Logging out is as simple as killing the current session. It takes just a small script, and we can link to the script directly to make a logout button.

session_destroy();

Let’s create a new file called logout.php. This file will handle destroying the session, and then displaying any additional information or redirecting the user.

<?php
session_start();
session_destroy();

header( 'Location: index.html' );

First we need to start the session so the server can identify it, just like on every other page. Without this, the server will have no session to destroy. We then call “session_destroy();” to get rid of the function, which logs the user out. After this, we redirect them to our index.html page (not created in this tutorial).

To have the client log out, one can provide a link to the logout.php page.

Wrapping Up

Hopefully everything is easily understood, but feel free to ask questions or notify me of any errors or bad practices I displayed on accident. I’d be glad to fix things right up.

As one will notice, our entire script is getting a bit messy. For example, our three-lined logout script almost seems unnecessary to be in a completely different file. I do this to separate everything out, and leave most of the coding design up do you guys. Hopefully this way will be the easiest to understand.

Once you get things set up and working though, it’s a good idea to refactor your code. This means to clean it up, group things, and do whatever to make the code more manageable. Here is a simple walkthrough on how to do basic refactoring: Diving into PHP: Day 5. In addtion, one could send out HTML forms to the same page and do the needed PHP actions there, and even start using Object-Oriented PHP to begin organization.

Next time we’ll go over and upload and shared documents area for the client, so you and the client can share any images, text, or other information easily and quickly.

Written By Kayla

Kayla Knight is a 20 year old college student, part-time web developer, freelancer, and blogger. Webitect is where she spends too much of her freetime, sharing interesting finds and valuable resources. Be sure to check out her portfolio.

6 Comments

  1. Cody Robertson

    July 28th, 2009 at 10:00 am

    Nice one Kayla, I do want to recommend one thing though, There is a better and more secure way to connect to a database now.

    Your Code
    [pre]
    $conn = mysql_connect(“localhost”,”root”,”");
    $db = mysql_select_db(“ClientArea”);
    [/pre]

    If I was going to go on about it I would do this
    [pre]
    $mysqli = new mysqli(‘localhost’, ‘user’, ‘pass, ‘dbname’);
    [/pre]

    Then after you call it, you have to do other thing a bit different like you can do.

    [pre]
    $mysqli->query();
    //or
    mysqli_query();
    [/pre]

    It has to be mysqli not mysql.

    Also, have you seen my emails? I can never seem to get a hold of you

  2. Colin McCormick

    July 28th, 2009 at 11:04 am

    Nice tutorial. I agree with Cody that you should use the object-oriented mysqli method for connecting to the database. Otherwise great tut.

  3. Justin

    July 28th, 2009 at 12:11 pm

    Thanks so much Kayla for the great tutorial(s)!

  4. Cody Robertson

    July 28th, 2009 at 12:29 pm

    Oh wow, just noticed pre tags don’t work in comments :/

  5. Mencha

    July 28th, 2009 at 05:10 pm

    Great great tutorial!!! Thanks very much, I’ve been looking for something like this for so long!! Thanks you very much!!!

  6. Andy Rixon

    July 30th, 2009 at 08:10 pm

    Great tutorial, well commented… just wondering, when will the next part be available :D