1

新しいタイプの犬を 10 秒ごとにユーザーにエコーするこの php スクリプトがあります。その 10 秒間にページがリロードされるたびに、犬は同じままです。10 秒以上経過すると、犬が変化します。

<head>
<title>New Dog Every Ten Seconds!</title>
<?php
$mysqli = new mysqli("localhost", "root","root","dogshow");
if ($mysqli->connect_errno) {
    printf("Connect failed: ", $mysqli->connect_error);
    exit();
}
?>
</head>
<body>
<?php
echo $currenttime = time();
echo '<br>';
echo $minute_ago = $currenttime - 60;
echo '<br>';
$result = $mysqli->query("SELECT * FROM dogs WHERE dateused<$minute_ago ORDER BY rand(ROUND(UNIX_TIMESTAMP()/10)) LIMIT 1");
$row = mysqli_fetch_array($result);
echo 'uid = ' . $row['uid'] . '<br>';
$uid = $row['uid'];
echo 'dogname = ' . $row['dogname'] . '<br>';
//$result = $mysqli->query("UPDATE dogs SET dateused=$currenttime WHERE uid=$uid");
?>
</body>
</html>

うまく機能しますが、ゲームを停止するエラーが 1 つあります。たまに同じ犬が二回出てくる!私がする必要があるのは、同じ犬が 2 回来るのを止めることだけです。

私はたくさんのことを試しました(一晩中それでした)が、何もうまくいきません!本当に、本当に助けていただければ幸いです。

データベースの概略は次のとおりです。

Table Name = dogs
id  |  name  |  dateused
------------------------
1   |  Rover |  1362960167
2   |  Chip  |  1362960123
3   |  Rex   |  1362960178
4

2 に答える 2

1

RAND()問題は、問題を防ぐために、カスタムでありながら創造的なシード値を信頼していることだと思います。

ROUND(UNIX_TIMESTAMP()/10)

同じシード値を使用すると、同じシーケンスが生成されます。ここで推測しているだけですが、同じシード値が単一の 10 秒間隔で生成されるため、シーケンスの最初の値は常に同じになるという考えから外れていると思います (その間隔の間)、同じ犬が毎回表示されます。

この考え方の問題点は、異なるシーケンスが同じ値で開始される可能性があることです。そのため、「ランダム」ではありますが、10 秒間隔が 2 つ連続して同じシーケンス値で始まる可能性があり、その結果、同じ犬が表示されます。

UPDATE(潜在的な解決策/推測)
現在質問にあるコードを使用して、UPDATE句を取り、保存されているタイムスタンプを「わずかに」変更できます。値を保存する代わりに、シード値に使用している値を$currenttime保存するだけです。ROUND(UNIX_TIMESTAMP() / 10)したがって、更新行は次のようになります。

$mysqli->query("UPDATE dogs SET dateused=ROUND(UNIX_TIMESTAMP() / 10) WHERE uid=$uid");

これを行うと、クエリ$minute_ago = round((time() - 60) / 10);でそのまま使用して使用し、機能させることができます。SELECT

これの背後にある理由は、ROUND(UNIX_TIMESTAMP() / 10)が と同様に、10 秒間隔ごとに同じ値を生成することround((time() - 60) / 10)です。したがって、どの 10 秒間隔でも、各方程式は不変の値を生成します。

于 2013-03-11T03:54:00.633 に答える
0

DISTINCTクエリで使用する

SELECT DISTINCT name, * FROM dogs WHERE dateused<$minute_ago ORDER BY rand(ROUND(UNIX_TIMESTAMP()/10)) LIMIT 1
于 2013-03-11T03:40:58.153 に答える