[advanced search]
 

Go Back   NamePros.com > Discussion > Web Design & Development > Programming

Programming PHP, Perl, Ruby on Rails, AJAX, HTML, XHTML, CSS, JavaScript, MySQL and any other coding topics.


Closed Thread
 
LinkBack Thread Tools
Old 12-23-2005, 03:40 PM   #1 (permalink)
Senior Member
 
legend2's Avatar
 
Join Date: Sep 2005
Posts: 1,102
141.05 NP$ (Donate)

legend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud of


An in-depth approach to a fair PHP ad randomizer [by Legend2]

An in-depth approach to a fair PHP ad randomizer
By legend2


The purpose of this tutorial is to shed some light on a way to improve php randomizers.
Suppose you got a heavy-traffic website, but a single banner ad spot.
Suppose too that you want to allow multiple advertizers to 'share' this space.

The biggest question an advertizer would ask here: will my ad get the same share of impressions as others showing on the same spot?

The fact is, using random functions to select an arbitrary 'include' is not that fair. No matter what the seed is, and depending on the size/number of possible ads to

include, some ad may be favorized more than others.

Our aim here is to divide the number of impressions equally among the advertized ads.


To give a clear idea of what I'm talking about here, we visualize teh following scenario:

We have an '/ads' folder under the root web directory of the website where the ads should show.
This folder will contain multiple files, each file correspoding to a different ad.

We also assume the web server is running PHP, and a MySQL DB.

We start off by creating a table called 'site_ads'. This table will contain two fields: 1) an auto increment field called 'id' which is the primary key for this table. This

field will uniquely identify each of the ads. 2) the file name corresponding to the ad, which can be found in the /ads directory. We'll call this field 'name'.

The query for this looks as follows:

Code:
CREATE TABLE site_ads (
id INT NOT NULL AUTO_INCREMENT ,
name VARCHAR( 100 ) NOT NULL ,
PRIMARY KEY (id)
)
Now, from now on, whenever you want to add a new ad to the rotation, simply insert a new entry in this table, and add its corresponding file in the /ads folder.
An example of such a query would be:

Code:
insert into site_ads('',"site1");
The corresponding file in the ads/ folder should then be called site1.php (note that we use a .php extension for the ad files, while the actual content can be static, such

as an <img>, but .php used as an example, in case you might need to add custom processing for every ad at an advanced stage).

We now reach our key idea: we do have the ads placed, and their corresponding entries in the database. How to divide impressions equally among them?

We create a new table in the database called 'counter'. The main purpose of this table is to keep track of the last ad viewed. This will help determining the next ad to

display. This table has one field, we call 'current' which will serve the purpose just stated. Note that if 'current' has a value of '5' it means fifth ad, and not the ad

with 'id' 5.
Why? The reason is that at some point, old ads will be removed, and others will be added. This will result in the 'id' field which is automatically generated (because of

its auto increment nature) having 'gaps'. Our approach will take care of this point.

The query for our new table is:

Code:
CREATE TABLE counter (
counter INT NOT NULL,
PRIMARY KEY (counter)
)
If this is the first time we run the randomizer, we would insert the value '0' which will correspond to the first 'id' the auto increment field of the site_ads table will

generate.

Such a query is:

Code:
insert into counter values('0');
We will follow a cyclic loop over all the ads. This means that once the counter reaches the last ad in the table, it will start off again from the beginning.


The following is a detailed PHP code which will illustrate the approch we are following (This is the code to be used in the actual ad space):

PHP Code:
<?

$dbname
= "database_name";
$databaseuser = "username";
$databasepass = "password";
$adsfolder = "ads/";

mysql_connect(localhost,$databaseuser,$databasepass) or die("couldn't connect");

mysql_select_db($dbname) or die("couldn't select database");

$counter_r = mysql_query("select * from counter");

$counter_r2 = mysql_fetch_array($counter_r);

$counter = $counter_r2[0];

if(!isset(
$counter)) {
    
mysql_query("insert into counter values('0')");
    
$counter = -1;
    
$total = 1;
}

$total_r = mysql_query("select * from site_ads");

$total_r2 = mysql_num_rows($total_r);

if(
$total_r2>0)
    
$total = $total_r2;

$newcounter = ($counter+1)%($total);

$ad_r = mysql_query("select * from site_ads limit $newcounter,1");

$ad_r2 = mysql_fetch_array($ad_r);

$ad = $ad_r2['name'];

mysql_query("update table counter set current = '$newcounter'");

mysql_close();

include
$adsfolder . $ad;

?>
The steps followed in the above code are:
- connect to the database
- fetch the current counter
- if counter is not initialized, initialize it to -1 for later increments to 0, and insert it in the database
- fetch the total number of ads in the database
- set total to 1 in case none exists yet
- get the next ad counter by incrementing the current one by 1 and using the math 'modulo %' to limit it to the number of total ads and give it a cyclic nature
- select the newcounter'th ad entry
- update the new counter location
- display the ad file.

The above code can be saved in a separate file called ads.php, and we can just include it from another php file.

PHP Code:
<? include "ads.php" ?>
Place the above line wherever the ad rotation usually should show.

Good Luck. (The code provided in this tutorial has not been tested, feel free to post comments in case you find any bug).

Legend2, All rights reserved.

Last edited by legend2; 12-25-2005 at 04:58 PM.
legend2 is offline  
Old 12-23-2005, 04:00 PM   #2 (permalink)
Eating Pie
 
iNod's Avatar
 
Join Date: Nov 2004
Location: Canada
Posts: 2,289
126.05 NP$ (Donate)

iNod has much to be proud ofiNod has much to be proud ofiNod has much to be proud ofiNod has much to be proud ofiNod has much to be proud ofiNod has much to be proud ofiNod has much to be proud ofiNod has much to be proud ofiNod has much to be proud ofiNod has much to be proud of

Special Olympics AIDS/HIV Cystic Fibrosis Save The Children Baby Health Cystic Fibrosis
Nice Post.

If you have mysql 4 or 4.1 I am not 100% sure which one you can always use the RAND command
PHP Code:
SELECT ad,id FROM site_ads ORDER BY RAND(NOW()) LIMIT 1;
Or if you want EVEN fast processing

PHP Code:
LOCK TABLES site_ads READ;
SELECT FLOOR(RAND() * COUNT(*)) AS rand_row FROM site_ads;
SELECT * FROM site_ads LIMIT $rand_row, 1;
UNLOCK TABLES;
These are just mysql querys you need to put them into PHP to make them work.
iNod.
__________________
I feel old.
iNod is offline  
Old 12-24-2005, 04:03 AM   #3 (permalink)
Senior Member
 
legend2's Avatar
 
Join Date: Sep 2005
Posts: 1,102
141.05 NP$ (Donate)

legend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud of


any other comments folks?
legend2 is offline  
Old 12-25-2005, 04:46 PM   #4 (permalink)
NPQ's PA, Slave, and On Call Coder

Technical Services

 
Eric's Avatar
 
Join Date: Mar 2005
Posts: 4,545
0.71 NP$ (Donate)

Eric has a reputation beyond reputeEric has a reputation beyond reputeEric has a reputation beyond reputeEric has a reputation beyond reputeEric has a reputation beyond reputeEric has a reputation beyond reputeEric has a reputation beyond reputeEric has a reputation beyond reputeEric has a reputation beyond reputeEric has a reputation beyond reputeEric has a reputation beyond repute

Save a Life Child Abuse 9/11/01 :: Never Forget Baby Health Marrow Donor Program AIDS/HIV Breast Cancer Cystic Fibrosis Ethan Allen Fund Animal Cruelty Ethan Allen Fund Ethan Allen Fund Cancer Alzheimer's Protect Our Planet Cancer Survivorship SIDS Child Abuse
Nice post legend. Ad rotation is so simple, yet some people find so hard to do. I find that alot of folks will use something like this:

PHP Code:
<?php

srand
((double) microtime * 100000);

$ad = rand(1, 5);

switch(
$ad)
{
  case
1:
    
$banner_code = "<a href=\"site.com\"><img src=\"images/banner1.gif\" border=\"0\" width=\"468\" height=\"60\"></a>";
    break;
  case
2:
    
$banner_code = "<a href=\"site.com\"><img src=\"images/banner2.gif\" border=\"0\" width=\"468\" height=\"60\"></a>";
    break;
  case
3:
    
$banner_code = "<a href=\"site.com\"><img src=\"images/banner3.gif\" border=\"0\" width=\"468\" height=\"60\"></a>";
    break;
  case
4:
    
$banner_code = "<a href=\"site.com\"><img src=\"images/banner4.gif\" border=\"0\" width=\"468\" height=\"60\"></a>";
    break;
  case
5:
    
$banner_code = "<a href=\"site.com\"><img src=\"images/banner5.gif\" border=\"0\" width=\"468\" height=\"60\"></a>";
    break;
}

echo
$banner_code;

?>
Which is definitely not a fair or accurate ad rotation system. Something like what you've written would def. work much better legend. Again, nice post. Rep added.

-Eric
__________________

Last edited by SecondVersion; 12-25-2005 at 04:56 PM.
Eric is offline  
Old 12-25-2005, 04:54 PM   #5 (permalink)
Senior Member
 
legend2's Avatar
 
Join Date: Sep 2005
Posts: 1,102
141.05 NP$ (Donate)

legend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud of


Thanks Eric :blush:
legend2 is offline  
Old 12-25-2005, 04:57 PM   #6 (permalink)
NamePros Regular
 
Palyriot's Avatar
 
Join Date: Jul 2004
Location: Seattle, Wa
Posts: 596
76.25 NP$ (Donate)

Palyriot is a jewel in the roughPalyriot is a jewel in the roughPalyriot is a jewel in the rough


Before I post my input, may I ask, is rand(0, 4) fair for 0-4?
Palyriot is offline  
Old 12-25-2005, 05:04 PM   #7 (permalink)
Senior Member
 
legend2's Avatar
 
Join Date: Sep 2005
Posts: 1,102
141.05 NP$ (Donate)

legend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud oflegend2 has much to be proud of


fair would be, if the script is called x times and you have y ads, then each ad would receive floor of x/y.
the rand function itself, might conceptually throw x times the same number. and it is more likely to favorise a number on another as the number it can pick from are narrow.
in my example, i force the choosing of each ad in a fair fashion.
so i a user loads the page at second a displaying ad number 1 then the next user, regardeless of the time frame, will see ad number 2.
legend2 is offline  
Closed Thread


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Tutorial: Getting started with PHP (The Basics) deadserious Webmaster Tutorials 60 11-17-2007 11:35 AM
Great Scripts for Sale With Resale Rights! Zeeble Scripts For Sale 20 01-04-2006 01:39 AM
Googlism - What does google think of you? deadserious The Break Room 55 12-15-2005 09:09 AM

Site Sponsors
Advertise your business at NamePros

All times are GMT -7. The time now is 11:49 PM.


Powered by: vBulletin® Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0
Template-Modifications by TMS
vBCredits v1.4 Copyright ©2007 - 2008, PixelFX Studios

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85