PHP:如何实现获取随机数并累加至20的持续执行功能?
嘿,这个问题我之前帮朋友处理过类似的,咱们一步步拆解解决哈!
首先得先理清楚核心矛盾:你现有的random.php脚本逻辑有点小问题——如果是靠cron每5分钟执行,那里面的header("Refresh:1")在命令行环境下完全不生效,而且你没把生成的$num存下来或者输出,别的脚本根本拿不到数据。咱们先把这个问题修正,再解决累加的事儿。
方案1:用本地文件做共享存储(简单易上手,适合小场景)
这种方式不用依赖数据库,几行代码就能搞定。
第一步:修改random.php(生成并保存随机数)
把原来的代码改成这样,让它每次生成随机数后写入到一个文本文件里:
<?php // 生成1-5的随机数 $num = rand(1, 5); // 把随机数写入到num.txt(路径可以自己调整,确保有写入权限) file_put_contents('num.txt', $num);
然后给这个脚本设置cron定时任务,每5分钟跑一次:
*/5 * * * * php /绝对路径/到你的/random.php
(注意替换成你服务器上PHP的实际路径和脚本的绝对路径)
第二步:编写累加脚本accumulate_total.php
这里分两种运行方式,你可以选适合自己的:
方式A:让脚本持续运行(CLI模式,直到累加完成)
这个脚本会一直跑在命令行里,每5分钟读取一次新的随机数并累加:
<?php // 初始化累加总数:如果之前有保存的结果就读取,否则从0开始 $totalFile = 'total.txt'; $total = file_exists($totalFile) ? (int)file_get_contents($totalFile) : 0; // 循环累加直到达到20 while ($total < 20) { $numFile = 'num.txt'; if (file_exists($numFile)) { $num = (int)file_get_contents($numFile); $total += $num; // 保存最新的累加结果 file_put_contents($totalFile, $total); echo "当前累加结果:$total(本次加了$num)\n"; } else { echo "还没生成随机数哦,先确保random.php正常运行~\n"; } // 每5分钟(300秒)执行一次循环 sleep(300); } // 达到目标后收尾 echo "🎉 累加已达到20,最终结果:$total\n"; // 可选:删除临时文件 unlink($numFile); unlink($totalFile);
运行方式:在命令行执行php accumulate_total.php,它会一直跑直到完成目标。
方式B:用cron定时执行(不用一直挂着脚本)
这个版本每次执行时检查当前累加进度,直到达到20后自动停止:
<?php $totalFile = 'total.txt'; $total = file_exists($totalFile) ? (int)file_get_contents($totalFile) : 0; // 如果已经达到目标,直接结束 if ($total >= 20) { echo "已经达到目标啦,无需继续累加~\n"; // 可选:清理临时文件 unlink($totalFile); file_exists('num.txt') && unlink('num.txt'); exit; } // 读取最新的随机数并累加 $numFile = 'num.txt'; if (file_exists($numFile)) { $num = (int)file_get_contents($numFile); $total += $num; file_put_contents($totalFile, $total); echo "当前累加结果:$total(本次加了$num)\n"; // 达到目标后清理 if ($total >= 20) { echo "🎉 已达到目标20,停止累加\n"; unlink($totalFile); unlink($numFile); } } else { echo "未找到随机数文件,请检查random.php是否正常运行\n"; }
同样给这个脚本设置cron每5分钟执行一次:
*/5 * * * * php /绝对路径/到你的/accumulate_total.php
方案2:用数据库做共享存储(适合复杂场景,更可靠)
如果你的环境有MySQL之类的数据库,用数据库存数据会比文件更稳定,尤其是多脚本协作的场景。
第一步:创建数据库表
先在你的数据库里建一张表:
CREATE TABLE random_accumulate ( id INT AUTO_INCREMENT PRIMARY KEY, latest_num INT NOT NULL, total INT NOT NULL DEFAULT 0, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );
第二步:修改random.php(写入数据库)
<?php // 替换成你的数据库连接信息 $host = 'localhost'; $dbname = '你的数据库名'; $username = '你的用户名'; $password = '你的密码'; try { $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $num = rand(1,5); // 插入或更新最新的随机数(用id=1来固定存储) $stmt = $pdo->prepare("REPLACE INTO random_accumulate (id, latest_num) VALUES (1, :num)"); $stmt->bindParam(':num', $num); $stmt->execute(); echo "生成随机数:$num\n"; } catch(PDOException $e) { echo "数据库错误:" . $e->getMessage(); }
第三步:编写累加脚本
同样可以选择持续运行或cron定时执行,这里给持续运行的版本:
<?php // 替换成你的数据库连接信息 $host = 'localhost'; $dbname = '你的数据库名'; $username = '你的用户名'; $password = '你的密码'; try { $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); while (true) { // 获取当前累加总数和最新随机数 $stmt = $pdo->query("SELECT total, latest_num FROM random_accumulate WHERE id=1"); $row = $stmt->fetch(PDO::FETCH_ASSOC); if (!$row) { echo "还没生成随机数哦,先运行random.php~\n"; sleep(300); continue; } $total = $row['total']; $num = $row['latest_num']; if ($total >= 20) { echo "🎉 累加已达到20,最终结果:$total\n"; // 可选:清空数据 $pdo->exec("DELETE FROM random_accumulate WHERE id=1"); break; } // 更新累加总数 $total += $num; $stmt = $pdo->prepare("UPDATE random_accumulate SET total=:total WHERE id=1"); $stmt->bindParam(':total', $total); $stmt->execute(); echo "当前累加结果:$total(本次加了$num)\n"; sleep(300); } } catch(PDOException $e) { echo "数据库错误:" . $e->getMessage(); }
关键注意事项
- 确保两个脚本都有读写文件/数据库的权限,不然会出现权限报错
- 如果用文件存储,因为cron是每5分钟执行一次,并发冲突的概率极低,基本不用额外处理
- 原
random.php里的header("Refresh:1")只在网页环境下有用,用cron执行的话一定要删掉,命令行环境不识别HTTP头
内容的提问来源于stack exchange,提问作者Saucepan
相关产品推荐
相关产品推荐

