PHP游戏体力恢复采用Crontab定时任务实现:通过独立CLI脚本每5分钟批量计算并更新用户体力,结合last_recover_time时间戳与预估逻辑确保实时显示,避免请求驱动导致的延迟与不一致。

PHP游戏网站用 Crontab 做体力恢复,核心是:把“定时给用户加体力”的逻辑从页面请求中剥离,交给系统级定时任务执行,避免用户刷新或登录才触发、导致延迟或不一致。
体力数据必须支持时间戳记录
不能只存当前体力值,要记录关键时间点:
- last_recover_time:上次自动恢复的时间(如 MySQL DATETIME 或 UNIX 时间戳)
- max_energy:用户最大体力(可随等级变化)
- energy_per_minute(可选):每分钟恢复多少点,或固定间隔恢复固定值(如每5分钟+1)
例如:用户最大体力为120,每5分钟恢复1点,最后恢复时间是 2024-06-15 10:00:00,现在是 14:30:00,中间隔了4.5小时 = 54个5分钟周期 → 可恢复54点(上限120)。
写一个独立的 PHP 恢复脚本(不依赖 Web 环境)
新建文件如 /var/www/game/cron/recover_energy.php,开头禁用超时、忽略用户中断:
立即学习“PHP免费学习笔记(深入)”;
#!/usr/bin/env php
<?php
// CLI专用:关闭输出缓冲、忽略用户中断
ignore_user_abort(true);
set_time_limit(0);
<p>require_once '/var/www/game/config/database.php'; // 自行适配你的DB连接</p><p>$pdo = get_pdo(); // 你的PDO实例</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill5233" title="btpanel phpsite 宝塔面板PHP网站"><img
src="https://img.php.cn/upload/skill/000/000/081/179040786932301.jpg" alt="btpanel phpsite 宝塔面板PHP网站" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill5233" title="btpanel phpsite 宝塔面板PHP网站">btpanel phpsite 宝塔面板PHP网站</a>
<p>宝塔面板 PHP 网站管理:站点创建、删除、启停、PHP 版本切换、域名管理、SSL证书管理、伪静态管理、数据库管理</p>
</div>
<a href="/xiazai/skill5233" title="btpanel phpsite 宝塔面板PHP网站" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><p>// 查询所有需要恢复体力的用户(比如:当前体力 < 最大值,且距离上次恢复已过阈值)
$stmt = $pdo->prepare("
SELECT id, max_energy, current_energy, last_recover_time
FROM users
WHERE current_energy < max_energy
AND last_recover_time < DATE_SUB(NOW(), INTERVAL 5 MINUTE)
");
$stmt->execute();
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);</p><p>foreach ($users as $u) {
$now = new DateTime();
$last = new DateTime($u['last_recover_time']);
$diffMinutes = $now->getTimestamp() - $last->getTimestamp();</p><pre class='brush:php;toolbar:false;'>$recoverInterval = 300; // 5分钟 = 300秒
$recoverAmount = floor($diffMinutes / $recoverInterval);
$newEnergy = min($u['max_energy'], $u['current_energy'] + $recoverAmount);
// 更新:体力 + 最后恢复时间设为 NOW()
$pdo->prepare("
UPDATE users
SET current_energy = ?, last_recover_time = NOW()
WHERE id = ?
")->execute([$newEnergy, $u['id']]);}
注意:该脚本应能直接在终端运行测试:php /var/www/game/cron/recover_energy.php,无报错、有日志更稳妥(可追加 file_put_contents 记录执行时间)。
配置 Crontab 每5分钟跑一次
用网站运行用户(如 www-data)编辑定时任务,避免权限问题:
# 切换到对应用户 sudo -u www-data crontab -e <h1>添加一行(每5分钟执行一次)</h1><p><em>/5 </em> <em> </em> * /usr/bin/php /var/www/game/cron/recover_energy.php > /dev/null 2>&1</p>
说明:
- 使用绝对路径调用
php(which php查看),避免环境变量差异 -
> /dev/null 2>&1屏蔽标准输出和错误(上线后建议改为记录日志,如> /var/log/game/recover.log 2>&1) - 不要用
$_SERVER或 session —— CLI 下不存在
前端显示需兼容“预估体力”逻辑
用户打开页面时,体力条不能只读数据库当前值,要实时计算“已过去但尚未被 Cron 执行的部分”:
- 查出
current_energy、last_recover_time、max_energy - 在 JS 或 PHP 中算出“理论上当前应有多少”,用于显示(不影响数据库)
- 例如:数据库存的是 80 点 + 上次更新是 10:00,现在是 10:12 → 预估为 82 点(每5分钟+1)→ 显示 82,但真实 DB 还是 80,直到 Cron 下次执行
这样体验更平滑,用户不会觉得“等5分钟才涨1点”。真正扣减体力仍走正常接口(扣完立刻更新 DB 和 last_recover_time)。


















