Week 8

Updated on 28 Dec 2018

HTTP Headers

In its simplest term, HTTP (Hyper Text Transfer Protocol) defines the way a web-browser and a web-server communicate with each other. When a web server sends a webpage to a user, it prefaces the content of the file with a HTTP header.

The HTTP header is not displayed on the browser, but rather gives the browser useful information such as the content type. Web browsers use the content-type header to decide how to handle a file. The HTTP header is also used to pass POST variables to the web-page.

PHP’s built in function header() can be used to add ‘headers’ to our web pages. The most common uses for using the header function are:

  • Redirecting the user to a different webpage.
  • HTTP authentication
  • Webpage caching

Questions:

  • What is meant by caching a webpage?
  • Why would you redirect to a different webpage?

Redirecting

Redirecting to a different webpage can be done in PHP code like this:

header("Location: http://127.0.0.1/COMP306/index.php ");
exit;

What will happen is that when the browser opens this page, it will read the ‘header’ and follow the instruction to go to the URL specified in the header statement.

HTTP Authentication

HTTP Authentication is used when you log onto phpMyAdmin. It can also be used with relative ease for any of the web pages that you build. The header command that is required for HTTP authentication (to display the login prompt) is shown below.

header('WWW-Authenticate: Basic realm= "Login Required "');

This only displays the login prompt. You still need to write your PHP code to check the username and password. The username and password entered by the user into the login screen is passed to your page via $_SERVER['PHP_AUTH_USER'] and $_SERVER['PHP_AUTH_PW'].

Page Caching

Web browsers and proxy servers frequently cache web pages to improve performance. Caching is a matter of referring to a saved version of a page rather than the original when a URL is requested. A user can adjust the caching policy on their browsers, and using PHP or Meta tags in the head of a HTML document, you can explicitly control caching.

Here is some PHP code that you can use to explicitly control caching.


header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . date("D, d M Y H:i:s") . "GMT");

//HTTP 1.1:
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);

//for HTTP 1.0
header("Pragma: no-cache");

Questions:

What do you think the first 2 header statements do? Is it possible to use this header code to prevent page caching without fully understanding the code? There is a special constraint placed upon the header function. What is it?

Finally

Even if you think HTTP headers is too technical, there is one header control that you might want to consider using on all your pages. It is a Cache-Control and the coding is shown below.

header("Cache-Control: private");

Have you tried using the back button on some of your PHP pages, especially the ones where information was posted to it? What happens is dependant upon the browser, however generally a warning will be displayed explaining that the page has expired or that it has to be built again with POST data and do you want to resend… The above piece of code can prevent that from happening.

You might find it interesting to know that HTTP headers also contain the response codes of a URL request. E.g. you might recognize these:

  • 404 Not Found
  • 401 Unauthorized
  • 200 Ok

Output Buffering

Output buffering allows you to write and execute your scripts as normal, but send data to the web browser when you want the data sent. Output buffering can affect the way in which you write your code because you always have the option of sending the buffer to the web browser or deleting the buffer without sending it to the browser.

Output buffering has several advantages. One is performance whereby the entire contents of a webpage can be sent in a single packet. The other is the way you write your code. Remember some functions (eg header) can only be called before any output has been sent to the browser! The use of Output Buffering can radically simplify the structure of your code!

Question:

  • How would output buffering simplify the structure of your code?

These are the most commonly used functions for output buffering:

  • ob_start
  • ob_end_flush
  • ob_end_clean

The example code shown below is only possible because of output buffering. If we didn’t have output buffering, then we’d have a PHP parse error because information would have been sent to the browser (Big title) before the header function was called.

<?php
ob_start();	//start output buffering

echo '<h1>Big title</h1>';

if(!isset($_GET['valid']))
  {
  ob_end_clean();		//delete the buffer
  header("Location: http://SomeOtherPage.com");
  exit;
  }

ob_end_flush(); //send everything to the browser.
?>

The header function is one of a handful of special functions that can only be called before ANY data has been sent to the browser, and in the example above if $_GET['valid'] has not been set, the script redirects the browser to another page.

Question:

  • Where could this type of coding be useful?

File Uploads

Building the capability to upload a file(s) to your website is a fairly straight forward process. First we create an upload form, and a basic one is shown below.

<form enctype="multipart/form-data" action="upload_image.php"
      method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="524288" />
<p>File:<input type="file" name="upload" /></p>
<p><input type="submit" name="submit" value="Submit" /></p>
</form>

There shouldn’t be anything in this code that you haven’t already seen before. The exception would be the enctype attribute which is used to indicate that the form needs to accept multiple types of data, including files. This attribute must be included in order to upload files.

The MAX_FILE_SIZE input element is used to specify the maximum file size permitted. This element needs to come before the file input, and kind of acts like the maxlength attribute of the input tag. It is not compulsory, but good practice to use.

Another important point to note with a file upload form is that it must use POST.

Submitting the Form

When the user clicks the submit button the file is uploaded to a temporary directory on the server. This directory is specified in the php.ini file. It can not be changed in a PHP script using the ini_set function.

However, we can not use the file that is placed in the temporary directory, so we have to move it to a location on our web server where it makes sense. An example is shown below.

if(isset($_POST['submit']))
  {
  //check for an uploaded file
  if(isset($_FILES['upload']) && 
    ($_FILES['upload']['type'] == 'image/jpeg'))
    {
    move_uploaded_file($_FILES['upload']['tmp_name'], 
                       "files/{$_FILES['upload']['name']}");
    }
  else
    ...
  }

So what are we doing here?

  • We check that the submit button has been pressed.
  • We check that the $_FILES array is set, AND that the file type is image/jpeg.
  • We move the temporary file to the location of where we want it.

The $_FILES array has 5 elements, and we’ve used 3 in this example.

type The MIME type of the file that was given to us by the browser.
tmp_name The temporary filename of the uploaded file when it was uploaded onto the server.
name The original name of the file (as it was seen on the user’s computer).

The other 2 elements are size (the size of the uploaded file in bytes) and error (The error code associated with any problem in the upload). There are 7 error codes that result in a file not uploading for whatever reason.

Error Codes:

0 There is no error, the file uploaded with success.
1 The uploaded file exceeds the upload_max_filesize directive in php.ini.
2 The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.
3 The uploaded file was only partially uploaded
4 No file was uploaded
6 Missing a temporary folder
7 Failed to write file to disk
8 File upload stopped by extension

You can check the status of the error codes after the form has been submitted either with the error code value or the corresponding upload constant. The following example demonstrates.

if($_FILES['upload']['error'] == 2)
   ...

Or using the predefined constant below.

if($_FILES['upload']['error'] == UPLOAD_ERR_FORM_SIZE)
   ...

If you were serious about reporting errors during the file upload process then you’d be checking all the error codes. Considering that there are currently 7 error codes resulting in a file not uploading you’d probably look at using a switch statement (as done in the text book on page 310) instead of using a series of conditional statements.

Questions:

  • It is usually recommended to change the name of the uploaded file to something other than what the original name was on the user’s computer. Why is this?
  • If a file is uploaded successfully, what would the size element be used for?
  • My example moves the uploaded file to a directory which is a child of the current directory where the script is running. Can the file be moved to a location outside the current directory or even outside the web-root?