Webnetics UK Ltd. - Forums
Rotating Banner System - Printable Version

+- Webnetics UK Ltd. - Forums (http://www.webneticsuk.com/forum)
+-- Forum: News & Announcements (http://www.webneticsuk.com/forum/forumdisplay.php?fid=2)
+--- Forum: VWDesigns Blog (http://www.webneticsuk.com/forum/forumdisplay.php?fid=12)
+---- Forum: Programming (http://www.webneticsuk.com/forum/forumdisplay.php?fid=17)
+---- Thread: Rotating Banner System (/showthread.php?tid=34)



Rotating Banner System - webnetics - 06-02-08

When we create a eCommerce site for our clients, one of the many things we always get asked, can have a rotating banner system. We have decided to put together some information on how to create a rotating banner system with php & MySQL.
You will need a limited knowledge of mySQL including how to create a mySQL table.

Introduction

Dynamic banner display means that the same banner advertisement changes with each refresh of the page, if ajax is used with php this can also be done in real time. This enables the display of ads on a Web site without having to clutter a single Web page.

Banners can be a viable source of income. Statistical information reporting the number of "hits" (the number of times the banner is displayed) and "clicks" (times the banner is clicked on) can be generated to justify the use of each banner.

This blog will provide instructions for developing a simple banner advertisement rotation system in PHP.

The banner advertisement script will enable you to:

· Automate rotation of a banner upon every refresh of the page.
· Keep track of banner statistics, including number of displays and actual clicks without the use of cookies, regardless of the banner destination.
· Switch banners in and out of active rotation without having to delete them from the database.

To achieve these features:

· Identifying each banner uniquely by assigning it a unique 32 byte ID.
· Give you the option to select the order in which the banners will be displayed.
· Generating the necessary HTML to display the banner correctly and dynamically based on the data provided and associated with the unique ID.
· Providing a means of tracking banner hits without interfering with its original destination link.

Banner Details

When structuring the database, the actual data associated with the banner follows a unique ID. The question is what data is really necessary and in what form should it take in the table?

For example, should the actual banner graphic be included within the database, say as a BLOB field, or should only the filename to the graphic be provided?

We have opted to include the banner graphic's filename as a string, represented by the column 'SRC'.

Note: The 'SRC' Field can only store a limited sized URL or file path; it is defined as VARCHAR (255).

The first field in our table structure is the ID field. This field serves as our unique banner identifier. Banner IDs can be defined using the statement below. In doing so, you can expect to receive a unique ID 32 characters in length:

PHP Code:
<?php $foo md5 (uniqid (rand())); ?>

The next three fields represent their HTML counterparts.

· HREF: Banner's URL, used as part of the <A HREF> tag.
· SRC: Graphic to be displayed when using the <IMG SRC> tag.
· ALT: Alternative banner description, when using the <IMG ALT> tag.

Note: From the fields listed above, only the ALT field is not mandatory and can be set to NULL.

The Hits and Clicks integer fields maintain display and click-through statistics respectively.

Two enumerated fields, Active and Pos, are used as follows:

· Pos field: Used as a flag field to indicate that this banner has already been displayed in this rotation cycle.
· Active field: Used to determine whether or not the banner is active.

The b_order integer field rounds out the table shown below. b_order defines the order in which a banner will be displayed. If you choose to display your banners in a particular sequence then this field will be mandatory. You would assign each banner a position and record it here.

Column Descripton Req'd?

ID Unique Banner ID, a MD5 32 Character String Y
HREF The URL to use in the banner's <A HREF> tag Y
SRC The Graphic to use in the banner's <IMG SRC> tag Y
ALT The alternate description for the banner graphic. Used for <IMG ALT> N
hits The Hit (or display) stetisticsfor the banner N
clicks The Click statistics for the banner N
active Is this banner currently in active rotation? Y
pos This fields serves as a "last used" identifier for PHP to track what banner was last displayed N
b_order The Order the banner will be displayed Y

The Database Definition

Displayed below is the mySQL table definition for the set of banner records.

Banner Table Definitions

Name Type Key
ID VARCHAR (32) Primary Key
HREF VARCHAR (255)
SRC VARCHAR (255)
ALT VARCHAR (255)
hits INT(10)
click INT(10)
active ENUM('T', 'F')
pos ENUM('A',NULL)

Note: When defining your table ensure that the fields ID, URL and file are set with the NOT NULL Property (or similar).

The mySQL Statement

The following CREATE TABLE statement may be used create the above table:

PHP Code:
CREATE TABLE banner(
ID VARCHAR(32NOT NULL PRIMARY KEY,
HREF VARCHAR(255NOT NULL,
SRC VARCHAR(255NOT NULL,
ALT VARCHAR(255),
hits INT(10) DEFAULT 0,
clicks INT(10) DEFAULT 0,
active ENUM('T''F'NOT NULL DEFAULT 'T',
pos ENUM('A'''),
b_order INT(10NOT NULL DEFAULT 1); 
You can include your file before any output to the user is sent, using the following code:

PHP Code:
include("/path/to/included.php"); 

Example

You have created a Web page and would like to generate some advertising revenue by inserting a rotating banner advertisement somewhere on that page.

The script presented in this blog is a self-contained application. However, it must be included before any output is sent to the user. The entire script is contained within a single file (complete with the function to display the banner).

To add a rotating banner:

· Insert the following function call: display_banner(); Calling this function with no parameters will cause the script to simply pick the next appropriate banner (meaning the next active banner available) and display the HTML behind it. The two optional parameters, $bannerID and $query_extra are used under special-case circumstances outlined below.
·
o $bannerID is used to force the script to display a specific banner based on its ID. When the specific banner is displayed, it does not affect the normal rotation pattern of the banners.
o $query_extra is used to include specific, relevant variables along with the banner itself when a user clicks on it. $query_extra is an array and must be formatted in the following way:

PHP Code:
array("var1name"=>"var1value""var2name"=>"var2value"); 

This feature is for the case where you might want to display a banner that links to another section of your site. If you use Sessions on your site, a normal redirect could potentially lose the current session data (if a GET method is being used instead of cookies). To compensate for this, $query_extra should be appended to the end of the banner's URL. This would enable you to keep your session data intact. This feature also could be used to transfer any extra required data regarding your banner to an external site if the situation warrants.

o display_banner() generates the proper HTML complete with a <A HREF=""> tag that points to $PHP_SELF and passes the proper banner ID back to itself (which then triggers the redirect logic).

Script Overview

With the example firmly in mind, the remainder of this section presents the contents of the banner script. The basic code-flow of the script is outlined below:

Step 1: Opening of page, Load pre-pended script file or execute include statement.
Step 2: Is a banner ID been given? If so, go to step 7. Otherwise, step 3.
Step 3: Load selected banner's data and add 1 to the banner's display statistics.
Step 4: Display HTML for banner using loaded information.
Step 5: Continue displaying page as normal.
Step 6: Reload the Web page and pass itself the banner ID of given banner clicked.
Step 7: Add 1 to the banner's click statistics.
Step 8: Redirect User to page specified in database for given banner ID.

What you need to do

· Open the page: Process a clicked banner if a banner ID is present. Otherwise, display the requested page as expected.
· Select a banner for display: Decide which banner to display.
· Generate the HTML: Output the required HTML.
· Special Case: Appending extra GET method data.

Open the Page

To track banner clicks, it is necessary to include the required code at the beginning of every page that will display the banner.

This code, nested within an if statement, is activated only when a banner has been clicked. Otherwise, the original page is displayed as expected.

Be sure to call the Display_Banner() function within the original page's script to display the banner at that page's preferred location. It is not necessary to call Display_Banner() on every page you include the auto-prepend script, rather only where you want a banner displayed.

Code Flow

· Check for the existence of $_bannerID (exists only if the user has clicked on a banner).
· Open a connection to the Database.
· Gather information about the banner from the database and validate the banner ID.
· Alter Statistics and re-direct user to the proper URL using the header() function.

PHP Code:
<?php
if(isset($_bannerID)) {
$DB = new DB_BANNER;
$DB->query("SELECT * FROM banner 
WHERE(uniqueid=
$_bannerID)");
if(
$DB->num_rows() != 0) {<BRDBINCCLKS($_BANNERID);
$url $DB->f("HREF"). $_query_extra;
Header("Location: $url");
}
}
?>

Select a Banner for Display

Having already created an auto-prepend file (see Prerequisites), our task now is to process the data and generate the required HTML to display a given banner.

In the Script Flow presented below, the <A HREF> tag of the banner is set to point to itself (i.e. the same page). It passes the ID of the banner that was just displayed. When the user clicks on the banner and the page is re-loaded (with the passed banner ID) the auto-prepended code is triggered and the appropriate action is taken.

Note: If we were not concerned with statistics, this step would have been a simple matter of putting the correct URL in the <A HREF> tag.

The script features two banner selection methods:

· Default method: Banners are displayed in a predefined order based on the b_order column in the table.
· Forced method: The script forces the display a specific banner based on it's banner ID.

Both of these methods are accessed by calling the function display_banner(). This function takes two optional parameters - a string that would contain a specific banner ID and a second string for extra query parameters.

Note: If you would like the script to behave in the default manner but still pass extra parameters using $query_extra, you must set the first parameter of display_banner() to the value "none" (case sensitive).

Code Flow

· Check to see if a banner ID was provided
· Check for the existence of any banners in the database
· Check to see if there are banners that have not been displayed yet. If not, reset the database so that all the banners can be displayed.
· By default, retrieve all of the banners that have not yet been displayed, ordered by the b_order column. Otherwise, retrieve the banner based on the banner ID provided.
· Take the first row returned and use it as the next banner to be displayed
· Construct the proper HTML for the banner based on the database data and the $query_extra array.

The $query_extra parameter of the display_banner() function is used to append extra GET method data to the end of the banner URL. This data should be an associative array representing the variables you would like to pass along with the banner ID when the banner is clicked (such as a session ID).

· If the banner was selected by rotation, meaning by default, flag the selected banner so that it will not be displayed twice in a row.

PHP Code:
<?php
function Display_Banner($bannerID "none"
$query_extra "") {
global 
$DB$_bannercfg$PHP_SELF;
if(
$bannerID == "none") {
$DB->query("SELECT * FROM banner WHERE pos='' LIMIT 1");
if(
$DB->num_rows() == 0) {
$DB->query("UPDATE banner SET pos='' WHERE(pos='A')");
}
$DB->query("SELECT * FROM banner WHERE(pos='') 
ORDER BY b_order LIMIT 1"
); 
} else {
$DB->query("SELECT * FROM banner 
WHERE(ID='
$bannerID')"); 
}
if(
$DB->num_rows() == 0) {
return 
false;
}
$DB->next_record();
$ban_data $DB->Record

Generate the HTML

In this stage of the script, the HTML is generated. The following basic HTML format is used to display our banner – the fields encased in '%' symbols define where PHP will fill in appropriate values:

PHP Code:
<A HREF="%HREF%">
<
IMG SRC="%SRC%" ALT="%ALT%" BORDER=0>
</
A

Note: Be aware that when extra data is passed along using the $query_extra parameter, it is appended in the proper format to the HREF field.

Once the banner has been displayed, the script ends unless the user clicks on the banner. In such a case, the variables $_bannerID and any data brought along with the $query_extra parameter is passed to itself (which in turn activates the source from the "Opening the page" section and takes the proper actions).

Code Flow

· Construct the HTML for the GET method.
· Make the extra query string.
· Construct the HTML for the banner and include the GET we constructed previously.
· Flag the banner.
· Echo the HTML.

PHP Code:
$get "?_bannerid=";
$get .= urlencode($ban_data['ID']);
unset(
$query);
if(
is_array($query_extra)) {
foreach(
$query_extra as $key => $val) { 
$get .= "&$key=".urlencode($val); 
}
}
$html "<A HREF='$PHP_SELF$get'>"
"<IMG SRC='$_bannercfg[srcpath]$ban_data[SRC]' "
"ALT='$ban_data[ALT] "
"BORDER='$_bannercfg[border]'>"
"</A>";
if(
$bannerID == "none") {
$DB->query("UPDATE banner SET pos='A' 
WHERE(ID='"
.$ban_data['ID']."')");
}
echo 
$html;
return 
true;
}
?>

Special Case: Appending Extra GET Method Data

Sometimes it is necessary to pass data along with a banner that, although is important to a third party or script, is irrelvant to this particular banner script.

For example, assume that in order to receive credit for the click-through (we'll call this ID parameter "tracker" with a value of "foo"), you need to pass an ID code to a URL that is being pointed to by the banner.

In order to pass this ID, you would need to include it as the $query_extra parameter when calling Display_Banner()as follows.

Code Flow

· Place the tracker ID code into a associative array with the key set as the parameter name (tracker) and the value set at it's value (foo).
· Pass the array to Display_Banner() as it's second parameter

PHP Code:
<?php
// Display a banner using default behavior
// But still passing the tracker parameter
$trackerID = array("tracker"=>"foo");
Display_Banner("none"$trackerID); 
// Display another banner specifically by
// passing it's ID and the tracker parameter
Display_Banner("dka932ndksla2931kdn1ksla231na23k"$trackerID); 
?>

The Script

Note: The PHP elements are found within the <?php and ?> marks.

The code contains comments preceded by // or /* and */ marks.

PHP Code:
<?php 
// Check to see if the banner ID flag is set
if(isset($_bannerID)) {
// Create an instance of the Database Layer 
$DB = new DB_BANNER;
// Get info about banner from DB 
$DB->query("SELECT * FROM banner 
WHERE(uniqueid=
$_bannerID)"); 
// Check to see if Banner ID is valid before doing 
// anything else 
if($DB->num_rows() != 0) { 
// Increment Click Counter 
dbIncClks($_bannerID); 
// Redirect user to new location, $_query_extra 
// is the Extra parameters that were given to the 
// script back in dbShowBan(). This feature is 
// for if you want a banner on your own site, to 
// your own site, but use sessions and don't want 
// the user to lose their session when they 
// click. 
$url $DB->f("URL"). $_query_extra;
Header("Location: $url"); 


function 
Display_Banner($bannerID "none"
$query_extra "") { 
// Grab the Database Layer and the Config options 
global $DB$_bannercfg$PHP_SELF
// Did we pass a BannerID? 
if($bannerID == "none") { 
// If Not, Grab the next in rotation 
// First, make sure that there is something to select
$DB->query("SELECT * FROM banner WHERE pos='' 
LIMIT 1"
); 
// If there is nothing, then everything has 
// been displayed
// Time to start from square 1 
if($DB->num_rows() == 0) { 
$DB->query("UPDATE banner SET pos='' WHERE(pos='A')"); 
}
// Finally, select the next banner 
$DB->query("SELECT * FROM banner WHERE(pos='') 
ORDER BY b_order LIMIT 1"
); 
} else {
// If so, Grab the requested Banner 
$DB->query("SELECT * FROM banner 
WHERE(ID='
$bannerID')");

// Make sure we grabbed something 
if($DB->num_rows() == 0) { 
return 
false;
}
$DB->next_record(); 
// Saved the data we got in a separate array 
$ban_data $DB->Record
// Construct the HTML for the GET 
$get "?_bannerid=".urlencode($ban_data['ID']); 
// Make the extra query string 
if(is_array($query_extra)) { 
foreach(
$query_extra as $key => $val) {
$get .= "&$key=".urlencode($val);


// Construct the HTML for the banner and include the GET // we constructed previously. 
$html "<A HREF='$PHP_SELF$get'>"
"<IMG SRC='$_bannercfg[srcpath]$ban_data[SRC]' "
"ALT='$ban_data[ALT] "
"BORDER='$_bannercfg[border]'>"
"</A>"
// Increment the hits
dbIncHits($ban_data['ID']); 
// Flag the banner used as displayed (if it was selected 
// by rotation) In special cases, we're not going to flag 
// anything 
if($bannerID == "none") {
$DB->query("UPDATE banner SET pos='A' 
WHERE(ID='"
.$ban_data['ID']."')");
}
// Finally, echo the HTML
echo $html;
// Return True
return true;
}
function 
dbIncClks($_bannerID) {
global 
$DB;
$DB->query("SELECT clicks FROM banner 
WHERE(ID='
$_bannerID')");
If(
$DB->num_rows() == 0) {
return 
false;
}
$DB->query("UPDATE banner SET clicks=".($DB->f('clicks')+1)." WHERE(ID='$_bannerID')");

function 
dbIncHits($_bannerID) {
global 
$DB;
$DB->query("SELECT hits FROM banner 
WHERE(ID='
$_bannerID')");
If(
$DB->num_rows() == 0) {
return 
false;
}
$DB->query("UPDATE banner SET hits=".($DB->f('clicks')+1)." WHERE(ID='$_bannerID')");
}
?>