PHP Tutorial

Step 8

PHP Tutorial

In this tutorial we will create a simple twitter copycat. In step 8 we will make our code more robust by adding error detection and handling.

Step 8

1. Let’s start with something small. When a user clicks on an username, we are sending them to a page that displays the tweets of that user. This page, pages/tweets/list_user.php, currently looks like this:

<?php
  include_once('../../config/init.php');
  include_once($BASE_DIR .'database/tweets.php');

  if (!isset($_GET['username'])) die('username missing');
  $username = $_GET['username'];

  $tweets = getUserTweets($username);  

  $smarty->assign('tweets', $tweets);
  $smarty->display('tweets/list.tpl');
?>

As you can see, if no username is received, we are just stopping execution and displaying an error message. That’s not very nice.


2. What would be nicer would be to redirect them to a valid page (e.g. the home page) and displaying an error message. The redirection part is easy; just change this:

if (!isset($_GET['username'])) die('username missing');

into this:

if (!$_GET['username']) {
  header("Location: $BASE_URL");
  exit;
}

Don’t forget to stop execution after doing a redirect or the PHP code will continue to execute. We are using !$_GET[‘username’] instead of !isset($_GET[‘username’]) because the first one also tests if the string is empty.


3. Now we need to display an error message in the other page. We could send that message as an HTTP parameter, but that gets messy quickly. The best approach would be to send it using a session variable. So we start by initializing our session in every page by adding this line to the top of our config/init.php:

session_start();

4. Now we can add an error message to the $_SESSION array. Let’s be safe and assume we might want to send more than one message at the same time and put those message in an array:

if (!$_GET['username']) {
  $_SESSION['error_messages'][] = 'Undefined username';
  header("Location: $BASE_URL");
  exit;
}

5. We want to make every page capable of receiving error messages so we should add our error handling code to the config/init.php file. This code will be responsible for sending those messages to the smarty processor and deleting them from the session so they are only displayed once. At the end of this file lets add:

if (isset($_SESSION['error_messages'])) {
  $smarty->assign('ERROR_MESSAGES', $_SESSION['error_messages']);
  unset($_SESSION['error_messages']);
}

6. The code that displays the error messages should also be executed in every single page. To accomplish that we will add it to the end of header.tpl template:

<section id="messages">
  {if isset($ERROR_MESSAGES)}
    {foreach $ERROR_MESSAGES as $error}
      <div class="error">{$error}</div>
    {/foreach}
  {/if}
</section>

7. One important word of advice about sessions. Session variables are kept in a server file. Each session has its own id and its own file where these variables are stored. The browser knows which session id to send to the server because it stores that value in a cookie (the first time session_start is called a new id is generated). By default that cookie is stored for the server that generated it but we can change its scope.

If you’re developing your site anywhere else besides the root of your webserver, you should change the path your session cookie is valid for. For example, if your site base URL is http://gnomo.fe.up.pt/~arestivo/example.twitter/ you should add this line to your init.php file before starting the session:

session_set_cookie_params(3600, '/~arestivo/example.twitter/');

This way, your cookies won’t interfere with other sites living in the same server.


8. Finally, lets add some styling to this new error message:

#messages {
  width: 40em;
}
#messages {
  width: 40em;
  margin: 0 auto;
}

#messages div {
  padding: 1em;  
  margin-top: 1em;
  border-radius: 2em;
}

#messages .error {
  background-color: #F99;
  color: #333;
}

In step 9 we will add some error handling to the registration form.