The blank one happens when the check fails and the function calls itself again.
BTW preg_match('/[0-9]/', $pass) is much faster than ereg.
My theory is that the function has nothing to return once it falls into a deeper recursive level. This theory seems true based on my rewrite of your code that works:
function forgot_pass()
{
global $chars, $i, $pass, $num, $tmp;
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
srand((double)microtime()*1000000);
$i = 0;
$pass = '' ;
while ($i <= 7)
{
$num = rand() % 33;
$tmp = substr($chars, $num, 1);
$pass .= $tmp;
$i++;
}
if (preg_match('/[0-9]/', $pass))
{
return($pass);
}
else
{
return forgot_pass();
}
}