The code in the subject line is something many of us have seen n imes already. The obvious drawback is that - despite srand() being able to take any integer value - it only ever receives values in the range [0..999999], thus locking you out of over 99% of possible sequences. (But, honestly, how often does that matter?)
If you don't supply a seed (or, more recently, don't seed at all), PHP will generate one, consisting of (effectively) microtime()*1000000, multiplied by a number from its own RNG (which it also uses for things like session IDs), multiplied by its own process ID.
Which is probably nice enough; but I found myself with cause to generate my own RNG seeds (maybe more on that later). And I didn't want to just go with the million-microsecond copout - in part because microtime() doesn't even have microsecond resolution on some platforms, reducing the range of possible sequences even further. It didn't need to be blindingly fast (it's only for seeding, not actual number generation), but I did want to limit myself to using microtime() as the sole source of nondeterminism.
I think this code gives decently uncorrelated and uniformly-distributed numbers (it could almost be a RNG in its own right), and does so over the range [0..2147483647]. In fact, I ran it a million times just now, and the seeds it came up with ranged from 807 to 2147482477. I'm still testing it out, so if anyone sees any holes in it, or improvements (yes, I wouldn't mind it being faster) - that's what this forum's for.
function generate_seed()
{
// We use the MD5 of microtime() to generate a list of 128 reasonably
// random-looking bits. We throw away all except the first 32. Then
// we force the first bit to 0, and convert the hex string that's left
// after all this into an integer (if the first bit was not reset, the
// resulting seed would have sometimes be a double).
// Upshot is a seed that lies in the range [0..2147483647].
//
// On subsequent runs, the MD5 of the new microtime is appended to the
// existing buffer, the first several hex digits are thrown away (exactly
// how many are discarded depends on the last hex digit of the hash), and
// then the truncation/resetting is carried out again.
static $buffer = '';
static $mod_int=array('0'=>'0','1'=>'1','2'=>'2','3'=>'3',
'4'=>'4','5'=>'5','6'=>'6','7'=>'7',
'8'=>'0','9'=>'1','a'=>'2','b'=>'3',
'c'=>'4','d'=>'5','e'=>'6','f'=>'7');
if($buffer=='')
{
$buffer = substr(md5(microtime()),0,8);
}
else
{
$now = md5(microtime());
$buffer = substr($buffer.$now,hexdec($now{31}),8);
}
$seed = hexdec($mod_int[$buffer{0}].substr($buffer,1));
if($seed<0) $seed=-$seed;
return $seed;
}