得到一个介于1-200之间的随机数,但忽略了从查询中读取的数字


Get a random number betwen 1-200 but leaves out numbers read from query

我需要获得一个介于1-200之间的随机数,但同时我需要防止选择一个已经用于特定REMOTE_ADDR(存储在表中)的随机数。

这就是我到目前为止所做的(我尝试了几种不同的方法):

$ip = $_SERVER['REMOTE_ADDR'];
$query7 = "
SELECT * 
FROM IP
WHERE IP = '$ip'
";
$result7 = mysql_query($query7) or die(mysql_error());
$rows7 = mysql_num_rows($result7);
while ($row7 = mysql_fetch_array($result7)){
    $id = $row7['ID'];
}

我使用随机数来选择要显示的图像,但我的用户抱怨为他们选择的图像不够随机;即,同一张照片经常被"随机"选中,有时会一遍又一遍地显示同一张图片。

如果有其他选项的话,它不一定是用PHP编写的。

类似的东西

// all ids from 1 to 100
$all = array_fill(1, 200, 0);
// remove used
foreach ($used as $i) {
   unset($all[$i]);
}
// get survived keys
$keys = array_keys($all);
// get random position, note that the array with keys is 0 based
$j = rand(0, count($all) - 1);
return $keys[$j];

运行select,而不是使用*,只选择id列。然后使用:

while($row7[] = mysql_fetch_array($query7));
do{
  $rand = rand(0,200);
}while(in_array($rand,$row7));

您可以在mysql中完成这一切。有一个表包含您的映像列表,另一个表则包含IP地址列表和已显示给该IP的映像。然后,您选择并连接这些表,并对结果进行随机排序。

SELECT image_id FROM images 
LEFT JOIN shown_images ON images.image_id=shown_images.image_id AND ip_addr=[#.#.#.#]
WHERE shown_images.image_id IS NULL
ORDER BY RAND() LIMIT 1;

向IP显示图像后,只需在shown_images表中插入一条带有IP和图像ID的记录即可。这将一直有效,直到用户看到所有图像为止。然后您可以删除记录并重新开始。

这个答案假设您有200个项目,并收集您不想显示的项目。或者,您可以只查询可用项的id并从中进行选择,您需要创建一个包含可用项的表

创建一个将连续数字映射到(非连续)可用数字的映射。假设数字1和3正在使用,则可以映射到2和4(依此类推)。

实际上,可以使用一个简单的数组(不关联)来实现这一点。你可以这样做:

$reserved = array(1, 3); // fill $reserved using your code
$available = array();
for ($i = 1; $i <= 200; $i++) {
    if (!in_array($i, $reserved)) {
        $available[] = $i;
    }
}
if (count($available) > 0) {
    $random_index = rand(0, count($available) - 1);
    $r = $available[$random_index];
} else {
    // Nothing available!
}

当您用完尚未显示的图片时,将没有任何选择。在这种情况下,count($available)将为零。解决此问题的一种方法是清除当前IP的显示图像列表,然后再次选择;另请参阅其他答案。