You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP实现无刷新随机日期查库:无记录时自动重试方案

解决无刷新自动重试随机日期查询的方案

首先,你的现有PHP代码是在页面加载时一次性执行的,如果随机选中的日期没有数据,页面就不会输出内容,而且没法自动重试——因为后端代码已经跑完了。要实现不刷新页面自动重试,我们需要把查询逻辑拆成「后端接口」+「前端JS请求判断」两部分,具体步骤如下:

第一步:重构后端为接口(PHP)

把随机日期生成和查询的逻辑封装成一个独立的PHP接口(比如get_random_match.php),让它返回JSON格式的结果,方便前端处理:

<?php
// 替换成你自己的数据库连接配置
$conn = mysqli_connect("localhost", "username", "password", "dbname");

$start = "2017-08-12";
$now = date("Y-m-d");
$now = date('Y-m-d', strtotime($now. ' - 7 days'));
$daty = array();
while($start<$now){
    $start = date('Y-m-d', strtotime($start. ' + 7 days'));
    $daty[] = $start;
}

// 循环尝试随机日期,直到找到有数据的日期或遍历完所有日期
$hasData = false;
$matchData = array();
$selectedDate = null;
while (!$hasData && !empty($daty)) {
    $rand_key = array_rand($daty);
    $random_data = $daty[$rand_key];
    // 移除已尝试的日期,避免重复尝试
    unset($daty[$rand_key]);
    $daty = array_values($daty);

    // 查询该日期是否有数据(用预处理语句防注入)
    $sql2 = 'SELECT count(*) as total from tab where Date=?';
    $stmt = mysqli_prepare($conn, $sql2);
    mysqli_stmt_bind_param($stmt, 's', $random_data);
    mysqli_stmt_execute($stmt);
    $result12 = mysqli_stmt_get_result($stmt);
    $row12 = $result12->fetch_assoc();

    if ($row12['total'] > 0) {
        $hasData = true;
        $selectedDate = $random_data;
        // 查询该日期的具体比赛数据
        $sql1 = 'select * from premier1718 where Date=?';
        $stmt1 = mysqli_prepare($conn, $sql1);
        mysqli_stmt_bind_param($stmt1, 's', $random_data);
        mysqli_stmt_execute($stmt1);
        $result1 = mysqli_stmt_get_result($stmt1);
        while($row1 = $result1->fetch_assoc()){
            $matchData[] = $row1;
        }
    }
}

// 返回JSON格式结果
header('Content-Type: application/json');
echo json_encode([
    'success' => $hasData,
    'data' => $matchData,
    'date' => $selectedDate
]);

// 关闭数据库连接
mysqli_close($conn);
?>

这里做了两个关键优化:

  • 后端循环尝试随机日期,直到找到有数据的,或者遍历完所有日期(避免无限循环)
  • 使用预处理语句替代直接拼接SQL,彻底避免SQL注入风险

第二步:前端用JS发起无刷新请求

在你的HTML页面中,用JavaScript的fetchAPI发起请求,拿到后端结果后自动判断,没数据就重新请求(或者根据后端返回的状态处理):

<!-- 用来展示比赛数据的容器 -->
<div id="match-container"></div>

<script>
// 定义请求函数,支持自动重试
async function fetchRandomMatch() {
    try {
        const response = await fetch('get_random_match.php');
        const result = await response.json();

        const container = document.getElementById('match-container');
        if (result.success) {
            // 渲染拿到的比赛数据
            container.innerHTML = '';
            result.data.forEach(match => {
                const matchItem = document.createElement('div');
                matchItem.textContent = `${match.HomeTeam} vs ${match.AwayTeam}`;
                container.appendChild(matchItem);
            });
            console.log(`成功加载 ${result.date} 的比赛数据`);
        } else {
            // 所有日期都没有数据,提示用户
            container.textContent = '暂时没有找到可用的比赛数据';
        }
    } catch (error) {
        console.error('请求出错,1秒后重试:', error);
        // 请求失败时自动重试(比如网络波动)
        setTimeout(fetchRandomMatch, 1000);
    }
}

// 页面加载完成后自动发起第一次请求
window.addEventListener('load', fetchRandomMatch);
</script>

前端逻辑说明:

  • 页面加载后自动触发第一次请求
  • 如果后端返回有数据,直接渲染到页面
  • 如果所有日期都无数据,显示友好提示
  • 请求出错时(比如网络问题),1秒后自动重试

额外优化建议

  • 提升查询效率:如果可选日期范围很大,循环尝试随机日期会有点慢。可以先查询所有有数据的日期,再从中随机选一个,效率更高:
// 替代原有的随机日期生成逻辑
$sql = 'SELECT DISTINCT Date FROM premier1718 WHERE Date BETWEEN ? AND ?';
$stmt = mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, 'ss', $start, $now);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$validDates = array();
while ($row = $result->fetch_assoc()) {
    $validDates[] = $row['Date'];
}

if (!empty($validDates)) {
    $randomDate = $validDates[array_rand($validDates)];
    // 后续查询该日期的具体数据...
}

这种方式直接从已有数据的日期中随机选择,不需要循环重试,性能更好。

内容的提问来源于stack exchange,提问作者user2759825

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:06:37