If you are creating a commercial web site using PHP, a little way down the track you should be considering advertising possibilities. Read about how John performs rotating banner ads.
Intended Audience This tutorial is intended for the PHP programmer interested in developing a useful and dynamic banner advertisement system using mySQL, PHPLIB, and PHP version 4.0 or higher.
You will need a limited knowledge of mySQL including how to create a mySQL table using the mySQL client and must have PHPLIB version 7 operational.
Readers interested in learning more about mySQL and PHPLIB before reading this tutorial are encouraged to refer to:
Overview
With the growing importance of Web page real estate, meaning the actual space that defines your Web page, banner advertisements have evolved from being displayed statically to being displayed dynamically.
Dynamic banner display means that the same banner advertisement changes with each refresh of the page. This enables the display of a myriad of ads on a Web site without having to clutter a single Web page.
Moreover, 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 tutorial provides instruction for developing a banner advertisement rotation system in PHP. Application scripts are based on a system running PHP 4.0 or higher with some sort of database to store our data (we will be using mySQL).
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, this tutorial will demonstrate that PHP is capable of:
- 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.
Note: Instruction for administering Rotating Banner Advertisement system will be the topic of a future Zend tutorial.
Learning Objectives In this tutorial, you will learn how to:
- Modify php.ini or use .htaccess files to auto-prepend scripts to all of your Web pages.
- Use PHPLIB's database class to perform queries against a mySQL database.
- Create a full-featured banner rotation system complete with active/inactive banners and automatic rotation.
- Generate hit/click statistics for each banner.
Definitions
- PHPLIB - A library of classes that provide a standardized way to perform many common tasks such as accessing a database and session management.
- MySQL – A fast and reliable open-source SQL database software that provides an efficient data storage for Web page data.
- Auto-prepend – A method of including PHP Code on every single page automatically.
Background Information
This tutorial relies on two software packages other than PHP. PHPLIB will be used to access the database needed for the script. This is done so that the script in this tutorial can be used regardless of the actual database software being used. For data storage, mySQL will be used as the database.
Note: Due to the flexibility of PHPLIB's database access, the code within this tutorial may work on other SQL databases with little or no SQL query modification. Consult the database software documentation as well as the PHPLIB manual for more information.
Prerequisites
As a prerequisite for creating a banner system, it is recommended that you:
- Define the database from which you will store and manage your banners' details. This tutorial utilizes mySQL as its DBMS of choice. You should define a banner's details, the database definition, and the mySQL statement.
- Configure PHP to automatically pre-pend a file.
Banner Details
Naturally, 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? For our tutorial, 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 $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:
CREATE TABLE banner(
ID VARCHAR(32) NOT NULL PRIMARY KEY,
HREF VARCHAR(255) NOT NULL,
SRC VARCHAR(255) NOT 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(10) NOT NULL DEFAULT 1); Configuring PHP to auto-prepend a file You should configure PHP to auto-prepend your script's necessary code. By using auto-prepend you make the script available to any page on your Web site.
Place your finished script in a separate file and include it with the following statement in your php.ini or .htaccess file:
auto_prepend_file /path/to/included.php3 However, provided that:
- Your Web hosting provider does not permit you to modify the php.ini file or include a .htaccess file, or
- You already use the auto-prepend feature to include a file before all of your pages (such as the PHPLIB prepend.php3).
You can include your file before any output to the user is sent, using the following code:
include("/path/to/included.php3"); Let's paint a scenario. 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 tutorial 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).
As such, to add a rotating banner:
- Include the script in your document using auto-prepend or an include() statement.
- 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.
- $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.
- $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:
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.
- 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 scenario 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
if(isset($_bannerID)) {
$DB = new DB_BANNER;
$DB->query("SELECT * FROM banner
WHERE(uniqueid=$_bannerID)");
if($DB->num_rows() != 0) { $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
<?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:
<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.
$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
// 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
// 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')");
}
?>
Orginally published on the Zend website
| DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware. |
More PHP Articles
More By John Coggeshall
developerWorks - FREE Tools! |
Join this webcast, to learn how the Rational Process Library can help with compliance issues, drive process improvement, and assist in service-oriented architecture (SOA) or Agile development. We will take a peek into the Rational Process Library with content around software and systems engineering (including RUP), operations and systems management, program and portfolio management, and asset and SOA governance. FREE! Go There Now!
|
|
|
|
Hear how IBM Rational Project and Portfolio Management integrated solutions help teams put the right tools and processes in place to maximize the effectiveness and efficiency of project teams and ensure that the business vision is being executed correctly. Learn how to automate and integrate requirements prioritization, top-down project planning, communications and controls, and methodology deployment to keep your scope, costs, and schedules under control. Tackle with an end-to-end approach the management of scope and scope changes, usage of methodology to control and empower project teams, and optimization of resources to align activity costs with the overall project plan. FREE! Go There Now!
|
|
|
|
Attend this launch webcast with Scott Hebner, Vice President of IBM Rational Marketing and Strategy, for an overview of Rational’s new software offerings and resources to help modernize and accelerate software innovation on i on Power Systems – while ensuring past application investments are protected and continue to grow. Learn how these solutions are helping customers extend their core i5/OS solutions toward modern architectures such as SOA and web technologies to deliver business improvements that stand the test of time. FREE! Go There Now!
|
|
|
|
Learn how you can extend modern application lifecycle management to IBM System z through the IBM Rational Software Delivery Platform (SDP). The Did you say mainframe? e-kit includes podcasts, webcasts, tutorials, white and red papers, demos, and articles designed to help ease the challenges of modernizing your enterprise. This complimentary kit for mainframe developers is a practical, how-to guide for making the most of an existing development environment, including the skills and infrastructure already in place at an established enterprise. FREE! Go There Now!
|
|
|
|
Visit IBM developerWorks to download a free trial version of WebSphere Business Modeler Advanced V6.1.1, IBM’s premier business process modeling and analysis tool for business users that offers process modeling, simulation, and analysis capabilities. IBM WebSphere Business Modeler helps you visualize, understand, and document business processes for continuous improvement. FREE! Go There Now!
|
|
|
|
This tutorial shows new users of IBM WebSphere Business Monitor Version 6.0.2 how to perform the "Hello World" equivalent for monitoring business process applications. It is intended to help you get familiar with the capabilities of the product. FREE! Go There Now!
|
|
|
|
Join this Rational Talks to You teleconference on December 11 at 1:00 pm ET to get tips on building your own plugins with Rational Method Composer. Get your questions answered! FREE! Go There Now!
|
|
|
|
Visit IBM developerWorks to try the IBM SOA Sandbox for connectivity. The SOA Sandbox for connectivity provides a trial environment with the tooling and components to help you explore how to effectively connect your infrastructure and integrate all of the people, processes and information in your company. Use the hosted sandbox to explore SOA techniques that streamline connecting existing IT assets together, as well as learn how to connect them to new business logic. FREE! Go There Now!
|
|
|
|
In this webcast, IBM Rational will discuss the importance of Web application security and will share techniques and best practices to introduce application security testing into current QA processes including: understanding common security vulnerabilities and techniques to integrate security testing with defect tracking and remediation systems in an effort to safeguard sensitive online information. FREE! Go There Now!
|
|
|
|
WebSphere Process Server delivers a unique integration framework that simplifies existing IT resources. Often, as IT assets grow to support business demand, so too does their complexity and manageability. In this webcast, we’ll discuss how WebSphere Process Server helps deliver an SOA infrastructure that provides a common model to orchestrate, mediate, connect, map, and execute the underlying IT functions. Discover how WebSphere Process Server simplifies integration of business processes by leveraging existing IT assets as reusable services without the complexities of traditional integration methodologies. FREE! Go There Now!
|
|
|
|
All FREE IBM® developerWorks Tools! |