views:

169

answers:

2

I have a function that outputs items in a different order depending on a random number. for example 1/2 of the time Popeye's and its will be #1 on the list and Taco Bell and its logo will be #2 and half the time \it will be the other way around.

The problem is that when a user reloads or comes back to the page, the order is re-randomized. $Range here is the number of items in the db, so it's using a random number between 1 and the $range.

  $random = mt_rand(1,$range);
  for ($i = 0 ; $i < count($variants); $i++) {
    $random -= $variants[$i]['weight'];
    if ($random <= 0) {
      $chosenoffers[$tag] = $variants[$i];
      break;
    }
  }

I went to the beginning of the session and set this:

if (!isset($_SESSION['rannum'])){
    $_SESSION['rannum']=rand(1,100);
    }

With the idea that I could replace the mt_rand in the function with some sort of pseudo random generator that used the same 1-100 random number as a seed throughout the session. That way i won't have to rewrite all the code that was already written. Am I barking up the wrong tree or is this a good idea?

A: 

Answering the question: It depends. It is one approach*.

But check out: http://www.php.net/manual/en/function.mt-srand.php. The PHP mt_rand is a Mersenne Twister, which is a PRNG (already) and has a seed function.

*However, if the backing source changes, you've still got it wrong. Oops :-/

pst
You answered the question well also and in fact I used both answers, but edorian answered first.
pg
+2  A: 

What should to the job is:

<?php
srand(1);
echo rand();
// 1804289383
srand(1);
echo rand();
// 1804289383
?>

or respective

<?php
mt_srand(1);
echo mt_rand(1, 100);
//58
mt_srand(1);
echo mt_rand(1, 100);
//58
?>

and saveing the seed in the session like you said

edorian
I really appreciate the advice. Works like a charm.
pg
Oh one question. There are other references to mt_rand elsewhere on my site in various wordpress plugins. What if there are other instances where mt_rand is used? For example akismet (a wordpress plugin) also uses mt_rand. Is there a way to set the seed only for certain instances of mt_rand?
pg
No you can only seed for every following mt_rand call. But that shouldn't really be a problem. I'll guess one could craft a case where it matters. If you _really_ ( _really_ ) need to be sure you get true random after your code you need the reseed from a true random source (like /dev/random ) again.Sorry for replying so late
edorian