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

Php 获取一个介于1-200之间的随机数,但忽略从查询中读取的数字,php,mysql,Php,Mysql,我需要得到一个介于1-200之间的随机数,但同时我需要防止选择已经用于特定远程添加的随机数(存储在表中) 这就是我迄今为止所做的(我尝试了几种不同的方法): 我使用随机数来选择要显示的图像,但我的用户抱怨为他们选择的图像不够随机;也就是说,同一张图片被“随机”选择得太频繁,有时会反复显示同一张图片 如果有其他选项,则不必使用PHP。此答案假设您有200个项目,并收集您不想显示的项目。或者,您可以只查询可用项的id并从中进行选择,您需要为该项创建一个包含可用项的表 创建将连续数字映射到(非连续)可

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

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

我使用随机数来选择要显示的图像,但我的用户抱怨为他们选择的图像不够随机;也就是说,同一张图片被“随机”选择得太频繁,有时会反复显示同一张图片

如果有其他选项,则不必使用PHP。

此答案假设您有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!
}
$reserved=数组(1,3);//使用您的代码填充$reserved
$available=array();
对于($i=1;$i 0){
$random_index=rand(0,计数($available)-1);
$r=$available[$random_index];
}否则{
//什么都没有!
}
当您用完尚未显示的图片时,将没有可选择的内容。在这种情况下,
count($available)
将为零。解决此问题的一种方法是清除当前IP的显示图像列表,然后再次选择;另请参阅其他答案。

此答案假设您有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!
}
$reserved=数组(1,3);//使用您的代码填充$reserved
$available=array();
对于($i=1;$i 0){
$random_index=rand(0,计数($available)-1);
$r=$available[$random_index];
}否则{
//什么都没有!
}

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

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

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

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

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

// 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];
诸如此类

// 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];

您可以在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显示图像后,只需在Showed_images表中插入一条带有IP和图像ID的记录。这将一直工作到看到所有图像为止。然后您可以删除记录并重新开始。

您可以在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显示图像后,只需在Showed_images表中插入一条带有IP和图像ID的记录。这将一直工作到看到所有图像为止。然后您可以删除记录并重新开始。

那么我不需要手动执行吗?因为这些数字一直在变化。请确保您的
$reserved
是最新的。这看起来不错,但我发现“语法错误,第5行出现意外的“{”我不明白为什么,它看起来对我来说是正确的。啊,我的坏,在
$reserved
之后应该有两个
,修复了它。现在它工作得很好,但我仍然有一个问题,假设我在查询特定IP所看到的图片时从数据库中得到了数字31、109、3、192,我是否将它们放入lite this:$reserved=array(31、109、3、192);是这样吗?我不必手动执行此操作吗?因为这些数字一直在变化。请确保您的
$reserved
保持最新。这看起来很好,但我遇到了“语法错误,第5行出现意外的“{”,我不明白为什么,我觉得它是正确的。啊,我的错,应该有两个
))
$reserved
之后,修复了它。现在它工作得很好,但我仍然有一个问题,假设我从数据库中获取数字31、109、3、192,当我查找特定IP看到的图片时,我是否将它们精简为:$reserved=array(31、109、3、192);是吗?更简单的建议:创建一个包含所有图像的列表,将其洗牌,存储在用户会话中,逐个拾取。不重复的随机列表。我从未使用过会话,我想这有点难学。简单建议:创建一个包含所有图像的列表,将其洗牌,存储在用户会话中,逐个拾取。使用out重复。我从未使用过会话,我想这有点难学
mysql\u fetch\u array
只检索一行,请参见。仅供参考:现在
$row7
将包含类似
{1},{3}
的内容。数组中的函数
将与
1
不匹配
。此外,修复后,如果所有数字都出现在
$row7
中,并且
兰德($min,$max)
包含