Coding My Own Ad Rotator

Hi

I have my home page and I want to display large images there from site members. I want to ensure that each image is displayed the same amount of time as all the other images. I could use a database for this but feel that is a slow method especially IF I get lots of traffic.

Anyone have any thoughts. Loading and modifying a text file. Not sure what the locking issues are on text files if any.

Thanks in advance.

Well i’m just gonna throw out there that it’ll probably be just as slow; however, here’s how to do it flat-file.


function adpull() {
 $files = file_get_contents('adlist.txt');
 $files = explode("\
",$files);
 $out = $files[0];
 array_push($files,array_shift($files)); //Move first to last.
 file_put_contents('adlist.txt',implode("\
",$files));
return $out;
}

I am not going to give you a solution because StarLion gave you a nice one.
BUT if you think at “Text file” vs “database” - the database will win: speed, structure, security
With a database you will also keep track of your views, clicks and others (important features for any marketing department)

Okay thanks guys.

I am surprised you think DB is faster than Text. Not that I am an expert I just thought file access would be much quicker??

With The database I would be looking at 2 queries, a select then update. Not sure if mysql has Stored porcedures maybe even a trigger?

Any thoughts. How would you go about it using mySQL.

Will take a look at Stored Procedures and Triggers.

Generally databases will be faster, since they are way more advanced at reading and writing disk, plus they keep caches to speed things up.

Yes, MySQL has both, but I don’t have any extensive experience with them, so I can’t help you out there.

Another thought to use would be Memcache. Just use the principle outlined by @StarLion; above, but read from and write memcache instead of a file. Since memcache is purely in main memory it probably won’t get any faster than that.

Okay.

Thanks guys.

I look at doing it with a stored procedure call. Failing that you’ve given me a few ways.

Thanks a lot.

I made a test for you

<?php

// db vs text

/*
CREATE TABLE IF NOT EXISTS `banners` (
`idbanner` bigint(20) NOT NULL AUTO_INCREMENT,
`link` varchar(150) NOT NULL,
`clicks` int(11) NOT NULL,
`views` int(11) NOT NULL,
`lastused` datetime NOT NULL,
PRIMARY KEY (`idbanner`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=101 ;
*/

$file = 'banners.txt';

// 1. DATABASE

$time1 = microtime(1);

mysql_connect('localhost', 'root', '');
mysql_select_db('test');

/*

// prepare 100 records

for( $i = 1; $i<=100; $i++ ) {
	mysql_query('
		INSERT INTO `banners`
		( `link` ) VALUES ( "This is my Banner no. '.$i.'" )
	');
	$banners[] = "This is my Banner no. $i";
	echo '<br />Added '.$i;
}
@file_put_contents( $file, implode("\
", $banners) );

*/

$q = mysql_query('
	SELECT `idbanner`, `link`, `clicks`, `views`
	FROM `banners`
	ORDER BY `lastused` ASC
	LIMIT 1
');
$record = mysql_fetch_assoc($q);
var_dump('Database record: ', $record);
mysql_query('
	UPDATE `banners`
	SET `lastused` = NOW()
	WHERE `idbanner` = '.$record['idbanner'].'
');

// 2. FILE

$time2 = microtime(1);

$files = file_get_contents($file);
$files = explode("\
", $files);
array_push($files, array_shift($files));
file_put_contents($file, implode("\
", $files)); 
var_dump('File record: ', $files[0]);

$time3 = microtime(1);

var_dump('----------------- Results -----------------');
var_dump('File: ', $time2-$time1, 'sec');
var_dump('Database: ', $time3-$time2, 'sec');

?>

Results: 0.0421 seconds for file VS 0.0056 seconds for database

5 banners
----------------
string 'Database record: ' (length=17)
array
'idbanner' => string '3' (length=1)
'link' => string 'This is my Banner no. 3' (length=23)
'clicks' => string '0' (length=1)
'views' => string '0' (length=1)
string 'File record: ' (length=13)
string 'This is my Banner no. 4' (length=23)

string '----------------- Results -----------------' (length=43)

string 'File: ' (length=6)
float [B]0.050672054290771[/B]
string 'sec' (length=3)

string 'Database: ' (length=10)
float [B]0.0024058818817139[/B]
string 'sec' (length=3)



100 banners
----------------
string 'Database record: ' (length=17)
array
'idbanner' => string '47' (length=2)
'link' => string 'This is my Banner no. 47' (length=24)
'clicks' => string '0' (length=1)
'views' => string '0' (length=1)
string 'File record: ' (length=13)
string 'This is my Banner no. 10' (length=24)

string '----------------- Results -----------------' (length=43)

string 'File: ' (length=6)
float [B]0.042107105255127[/B]
string 'sec' (length=3)

string 'Database: ' (length=10)
float [B]0.0056848526000977[/B]
string 'sec' (length=3)

You don’t need stored procedures or triggers for this.
You may use stored procedures but I doubt you really need to.

Thanks for that.

I just thought an SP would be better. Doing it all in one instead of 2 calls (Select,Update) to the database. The speed is marginal so will go for the DB version. I don’t really need to check clicks to a certain degree as the banners will be placed on page using an google analytic event.

If you’re going to use MySQL for the database, please be aware that the mysql_* extension is now deprecated as of the current version of PHP and will very likely be removed from the next 5.x version and will likely not be in PHP 6.x (when it eventually is released). You should migrate over to either the mysqli_* extension or to PDO. PDO is a better choice as it doesn’t tie you down so much to a particular database server software.

If any of the code for your ad-rotator is going to send anything to the database, from any user-submitted source (cookies, get, post, etc) then you should use Prepared Statements to prevent SQL Injection attacks. Have a read of this article from the PHP manual, it shows how to use prepared statements with PDO and also explains the principle.

I’ll throw a caveat onto this result; the example data shown here is for a LOCAL database. If your provider hosts their database servers remotely (like GoDaddy does), this will affect the overall time of retrieval.

Ok, I didn’t know about this approach.
However, this is just a hosting “bad practice” (I will not debate this, maybe there are reasons like security and others) but as programming it’s nothing you can do about it.
Still, I will keep my idea that “database is better!” :slight_smile:

edit // About what SpacePhoenix said, I use PDO (and I recommend it) but I used core functions to make it as fast as possible.
This was just to prove my point, I don’t use mysql_* since PDO appeared.