Navigation


Lesson: Simple applications

Goals

We'll look at how you start binding pages together to create entire applications that remember things from page to page (session variables, and including/requiring files). You'll use your login system to protect an entire set of pages.

Notes

Read this tutorial on PHP sessions.

Sessions let you create applications, that is, sets of pages that hang together to create a complete system. For example, you can use session varibles to:

  • Remember whether a user has logged in.
  • Remember what items a user has added to his or her shopping cart.
  • Remember a user's name, and show it on pages.

Changing the simple log in system

Let's change the log in system we looked at earlier to use session variables. Here's what we had:

Log in system

Here's the code we had for check_login.php:

<?php
//Get user input.
$userName = $_POST['userName'];
$userPassword = $_POST['userPassword'];
//Log in OK?
if ( $userName == 'Willow' && $userPassword == 'Tara') {
    header('Location: login_success.php');
    exit();
}
//Jump to bad login.
header('Location: login_fail.php');
exit();
?>

You can try the new system. You can download the code.

Let's change check_login.php to this:

<?php
session_start();
//Get user input.
$userName = $_POST['userName'];
$userPassword = $_POST['userPassword'];
//Log in OK?
if ( $userName == 'Willow' && $userPassword == 'Tara') {
    $_SESSION['logged in'] = 'ok';
    $_SESSION['user name'] = $userName;
    header('Location: index.php');
    exit();
}
//Jump to bad login.
header('Location: login_fail.php');
exit();
?>

This time, when the user logs in successfully, the program stores two session variables. The first is a flag to show that the login was successul. The second is the name of the user. If log in succeeds, the code jumps to index.php, the application's home page.

Other pages can check these variables. Let's looks at index.php:

<?php
session_start();
//Logged in?
if ( $_SESSION['logged in'] != 'ok' ) {
    header('Location: log_in.php');
    exit();
}
?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "
        http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Wonderful Application</title>
</head>

<body>
<h1>Wonderful Application</h1>
<p>User: <?php echo $_SESSION['user name']; ?></p>
<p>Main menu</p>
<ul>
    <li>(Menu items)</li>
    <li><a href="logout.php">Log out</a></li>
</ul>
</body>
</html>

First, the program checks whether the log in flag is set. If it isn't, then the program immediately jumps to the log in page. This is our security. Every secured page will only display if $_SESSION['logged in'] has the value 'ok'. The program check_login.php sets $_SESSION['logged in'] if the user supplies the proper user name and password.

Notice that index.php also shows the user name. check_login.php stores the user name in $_SESSION['user name'].

The log out page destroys the session variables that check_login.php created.

<?php
//Logout
session_start();
unset($_SESSION['logged in']);
unset($_SESSION['user name']);
session_destroy();
header('Location: log_in.php');
exit();
?>

Then it heads back to the log in page.

The following code is at the top of every page you want to protect:

<?php
session_start();
//Logged in?
if ( $_SESSION['logged in'] != 'ok' ) {
    header('Location: log_in.php');
    exit();
}
?>

Making maintenance easier

If you want to protect 40 pages, then all of the pages would have the code to check that $_SESSION['logged in'] is set. What if you needed to change the code? Then all 40 pages would have to be changed. It would be easy to miss one, and that would compromise security.

A better way to do it is to use the include or require statements. They read in the contents of a file into PHP code. You should read more about the statements.

In our case, we would take the last code fragment above, and move it to a file, maybe called verify_login.php. Then we would add that code at the top of every page we wanted to protect, like this:

<?php
require 'verify_login.php';
?>

So, index.php would start like this:

<?php
require 'verify_login.php';
?><!DOCTYPE HTML PUBLIC ...

The contents of the file verify_login.php would be read in and executed, as if it had been typed into index.php. Every page we want to protect would have the require statement.

Now, if we want to change the code, we change one file, verify_login.php. Every page that uses the file would be protected.

Files like verify_login.php are often put into a library directory, so the code that uses them has to have the right path. For example:

<?php
require 'lib/verify_login.php';
?><!DOCTYPE HTML PUBLIC ...

 

Exercises

Exercise 1. Page counting

Write a program that counts the number of times it has been accessed in a session. Each time the page is refreshed, the count goes up by one.

Try it.   Solution (try it yourself first)

Add a link the user can click to clear the count.

Exercise 2. Notes page

Create a page that accumulates user notes. Every time the user types a note, it is added to the list.

Try it.   Solution (try it yourself first)

Add a link the user can click to clear the notes.