dink

I need to do some page rotations, and I can't get it figured out.  I want to test some things on one of my sites, kinda-sorta split testing.  My searches on the big G leave me with acid sto

mac

 h and profane comments shouted at the monitor.

What I have in mind is this:  I have a link on my page like so 'more.

php

 '.

When a visitor clicks the link, the script in 'more.

php

 ' decides whether to show 'page1.

php

 ' or 'page2.

php

 '.  The result should be, first click goes to page1, second click goes to page 2, third click to page1, fourth click to page2, and so on. 

With only two pages to test, I thought it would be easy enough.  Hah.  I'm two wheels short of having a tricycle here.

If I could write code it might look like this:

//more.

php

 

<?
$count = something;  // ya right

if $count is odd {
header("Location: www.mysite.com/page1.

php

 ");
}

else {
header("Location: www.mysite.com/page2.

php

 ");
}
?>



So, how do I get $count and how to know which click has happened?

Any (and all) help greatly appreciated.

Bompa

The code, itself, can not keep track of first, second, third.

You would need to save that tidbit to a file.

I ran into the same situation when I wanted to rotate two ad blocks on every page load
which had different aff IDs.

1. Open the save_to.txt file and read that value, which would indicate what happened last time.
2. Do a comparison.
3. Save the current thing overwritiing save_to.txt.

I would give you the

php

  code if I knew

php

 .  Applause


Bompa

dink

I don't know any

perl

  so we're even there.  LOL

I've investigated a cookie option.  Where I would set a cookie when a visitor loads the page.  Then check to see if there is a cookie, if so load page1, if not load page 2, etc.  Instead of incrementing tho, one or the other (if else) would have to clear the cookies.txt file.

I've looked at a bunch of tracking scripts, but don't see anything in any of them that would seem to work here.

There seem to be quite a few taguchi type split testing scripts for sale, but I'm cheap.

Maybe when the Brits wake up tomorrow we'll get some action on this.

cdc

Hey dink, Bomps is right that you'll have to store it on your disk somehow (either with a file, which I wouldn't recommend for reasons I won't get into or a database, which is what you should use).

Your cookie idea won't work because the cookie will only be able to tell you if the current visitor has been there before and if I understand you correctly you want visitor A to see page 1, visitor B to see page 2, and so on.

Honestly, if you're afraid of using a database your best bet is to just use a random number instead of a counter. It won't be perfect in the sense that visitor A will see page 1 and visitor B will see page 2 (they may both see page 1), but in the end it will even out. I'm assuming you're using this for split testing landing pages. Using the random number will even out your stats close enough that it shouldn't matter, particularly if you're sending alot of traffic (the more traffic, the more likely your results will be 50/50).

Anyway, here is the code that uses the random number:


$count = rand(0, 1);


Then just check if count is either 0 or 1.

thedarkness

If getting them exactly split in sequence is not important you could do something like this;

<?
$count = rand( 1, 500 );

if( $count % 2 ) {
header( "Location: www.mysite.com/page1.

php

 " );
}

else {
header( "Location: www.mysite.com/page2.

php

 " );
}
?>


It should give you pretty much an even split over a decent run.

HTH,
td

@cdc: Saw your post but I'd already completed mine, virtually the same take on the issue.

nutballs

i agree with dark and cdc. I would do a randomizer

I do plenty of that. works out pretty even. the longer you run, the more even it gets.

dink

Thanks folks.  Got a good idea of how to proceed now.

@cdc..Not afraid of a database.  Use them alla time.  This code needs to work on servers where I don't have database privileges.

I believe that I can make it work with cookies too.  I'll be checking that later.

@NB, td,  Ya I have a random function that I use quite a bit.  Matter of fact I should post one that is easy to use.

thedarkness

Just thinking about this I reckon you could do what you want with

AJAX

  as well (many ways to skin this cat prolly)

Cheers,
td

greenway

quote author=thedarkness link=topic=141.msg760#msg760 date=1177836056

If getting them exactly split in sequence is not important you could do something like this;

<?
$count = rand( 1, 500 );

if( $count % 2 ) {
header( "Location: www.mysite.com/page1.

php

 " );
}

else {
header( "Location: www.mysite.com/page2.

php

 " );
}
?>




Should if( $count % 2 ) {
be if( $count % 3 ) {

because

php

  includes zero as a random number so you always have to add one back on ?

This is how I do it:

I make 2 text files that have the code changes:
mypage-1.txt    mypage-2.txt

<?

php

 
    srand(time());
    $random = (rand()%2)+1;
    include('mypage-' . $random . '.txt');
    ?>

thedarkness

No, my code only has to evaluate to true or false (1 or 0) and switches dependant on that.

Cheers,
td

perkiset

Man I've been thinking about this since I first read the thread this afternoon, and since you don't have DB access, you probably won't have anything fun like APC or memcached, nor even SEMV (semaphores and mutex support) - so it is difficult to see how you could write a smooth and accurate distribution device.

So I'm afraid that I agree as well, a randomizer will even out nicely if run long enough and that's probably the best you're going to get.

/p

thedarkness

No chance to use

AJAX

  to call a back end script using XML-RPC to say "what page should I load?" perk?

Then the back end script keeps track of what page it allocated last time by dropping it to disk and reading on the next run? I know it's a little bit ugly and prolly not scalable but it could be done couldn't it ([in a Darth Vader voice] The

AJAX

  is weak in this one)?

Cheers,
td

perkiset

TD I think that that would be just more ketchup on an already crappy meatloaf.

The deal is that you'd still have the "which page do I dispatch" issue on the backside, and now you've got more complications on the front side about it as well... this challenge is really that the right tools for the job are not available on the backside regardless of the frontend technology. The BEST option would be to cobble together some kind of database access so that you had the ability to dispatch and track precisely... but it just doesn't look like that's an option here.

/p

dink

Actually have to give credit where credit is due.  Google search finally paid off.  Still scraping saliva and expletives off of the monitory tho.  Applause

This is index.

php

 .  Also needed are page1.html and page2.html

<?

php

 

// Collect data

$log = file_get_contents("ct.txt");
$data_split=explode("%",$log);
$count = "0";

// Each page to be tested is put into a variable

$page1=file_get_contents("page1.html");
if (file_exists("page2.html"Applause){
$page2=file_get_contents("page2.html");
} else {$page2=$page1;}

// If you visit this page, you'll see both versions.

$remote_address = getenv("REMOTE_ADDR");

if ($remote_address == "$data_split[0]"Applause {

echo "<center><p><A HREF=page1.html target=_blank>Page 1</a>&nbsp;&nbsp;||&nbsp;&nbsp;<A HREF=$data_split[1] target=_blank>Test Results</a>&nbsp;&nbsp;||&nbsp;&nbsp;<A HREF=page2.html target=_blank>Page 2</a></p>$page1</center>";

} else {     

//Here's what happens when someone else visits.

// Record Referrer

$log = file_get_contents("referrers.txt");
$referrer_split=explode("%",$log);
$referrer_split2=explode("%",$log);

$count = 9;

while ( $count > 0) {
$referrer_split[$count-1] = $referrer_split2[$count];
$count--;
}

$referrer = $_SERVER['HTTP_REFERER'];
if ($referrer != ""Applause {
$referrer_split[9] = "<A HREF=$referrer target=_blank>$referrer</a>";
} else {$referrer_split[9] = "Typed in or other";}

//Set cookie if not already set.

if (!isset($page)) {

//Find which page is ready for the visitor.

$AorB=rand(0,1);

//Set a cookie that assigns which page this visitor will see from now 'til 2 weeks

setcookie("page",$AorB,time()+1209600,"/",".$data_split[2]",0);

// Let the counter know to count this visitor

$count = "1";

} else { $AorB = $HTTP_COOKIE_VARS["page"]; }

// Display one page or the other and add a visitor to the correct stat

if($AorB == "0"Applause {

echo "$page1";

if ($count == "1"Applause {
$data_split[3]++;
}

} else {

echo "$page2";

if ($count == "1"Applause {
$data_split[5]++;
}
}

// Update ct.txt

$data_group=implode("%", $data_split);

$log=fopen("ct.txt","w");
fwrite($log, $data_group);
fclose($log);

// Update referrers.txt

$data_group=implode("%", $referrer_split);

$log=fopen("referrers.txt","w");
fwrite($log, $data_group);
fclose($log);
}                                                   
?>


ct.txt and referrers.txt are pre-populated with 0%0%0%0%0%0%0 and .%.%.%.%.%.%.%.%.%. respectively.

The two flat files solve the no database problem for cheap servers.

This does more than I need, but does the part I need done, done.  (Whoa.  double need + double done = needlessly overly cooked)

Betcha this could be hacked to do some other interesting things.  Applause


perkiset

If you're going to go OS files, then you should at the very least look at flock() - it is an advisory/cooperative style file locking mechanism that might at least give you some notion of who's got files open at any given time. Although pretty durn quick, this system still relies on the notion that two processes will not be reading/writing the files at the same time. I have personal experience with a couple processes writing to a file at the same time and the resulting data in the file being completely torched.

Even flock() though will fail on several systems for a variety of reasons. The reason to use a DB is to have the concurrency issues handled. I mentioned SemV (System V actually, Semaphores and system messages for

PHP

 Applause which would allow you to do system-wide locks and advisories against files ie., handle your concurrency probabilities. It does not take any external libs, but is often not built by default with

PHP

 , so it may not be available to you. Check here:

http://www.

php

 

.net

 /manual/en/ref.sem.

php

 

and at least you can see what the larger systems do. I use this and it works great. I'd simply be cautious of any system that is targeted for high volume but relies on the hope that two processes will not collide.

Applause
/p

dink

Thanks for that.  Hadn't even considered the potential for concurrent problems.

There is a real possibility of high volume on one site.

dink

After reading this: http://www.

php

 

.net

 /manual/en/ref.sem.

php

 

and this:  http://www.

php

 -mag

.net

 /itr/online_artikel/psecom,id,448,nodeid,114

I think I'd better stick with a simple rand() until my understanding increases.

Will

php

 .info reveal the presence of SemV?

perkiset

Yep - it'll look like "--enable-sysvsem" on the compile line (at the top) and after all of the big blocks of info, in "Additional Modules" you should see "sysvsem." I am just looking at the text of it, not the HTML version so I don't know how pretty it'll be (or not).

/p

thedarkness

So the actual locking mechanism is acheived through sem_acquire and sem_release in a similar way to how you would use "critical section" code in C++ etc.?

Very cool, I

learn

  a lot in this place (it's very mental).

Cheers,
td

perkiset

Zactly. semaphores and mutexs are old world, but still really powerful. When you grab one you get a guaranteed unique hold on it till you let it go... when you have it, is when you do your critical section stuff.

Delphi had that as well - it was something like "critical { } or something that was a single thread choke point. Man that's a long time ago now...


Perkiset's Place Home   Politics @ Perkiset's