如何使用PHP存储获取的JSON数据,并在本地文件更新超2小时后触发更新以规避免费API请求限制?
没问题,这个需求其实非常实用——用PHP做一个API数据的本地缓存层,只有当缓存超过2小时才重新拉取远程数据,刚好能把每日请求次数控制在12次以内,完美避开免费API的调用限制。我给你一套完整的可落地方案,分步骤来:
核心逻辑
咱们的思路很简单,就是让PHP脚本充当一个“缓存代理”:
- 先检查本地是否有缓存的JSON文件
- 如果有,判断文件最后修改时间和当前时间的差是否超过2小时(7200秒)
- 要是文件不存在,或者已经过期,就远程拉取API数据并保存到本地
- 最后不管用缓存还是新拉取的数据,都输出JSON格式给前端调用
完整代码实现
你可以创建一个名为fetch-api-cache.php的文件,代码如下:
<?php // 配置项 $apiUrl = 'https://your-api-url-here.com/data.json'; // 替换成你的API地址 $cacheFile = './cache/api-data.json'; // 缓存文件的存储路径 $expiryTime = 7200; // 过期时间,单位秒,这里是2小时 // 确保缓存目录存在 $cacheDir = dirname($cacheFile); if (!is_dir($cacheDir)) { mkdir($cacheDir, 0755, true); } // 检查缓存是否有效 $useCache = false; if (file_exists($cacheFile)) { $lastModified = filemtime($cacheFile); if (time() - $lastModified < $expiryTime) { $useCache = true; } } // 处理数据获取 if ($useCache) { // 读取本地缓存 $data = file_get_contents($cacheFile); } else { // 从API拉取数据(用CURL更可靠,避免file_get_contents被禁用) $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $apiUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 如果API需要请求头(比如API密钥),可以在这里添加 // curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer YOUR_API_KEY']); $data = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // 只有当API请求成功时,才更新缓存 if ($httpCode === 200 && !empty($data)) { file_put_contents($cacheFile, $data, LOCK_EX); // LOCK_EX避免并发写入问题 } else { // 如果API请求失败, fallback到旧缓存(如果有的话) if (file_exists($cacheFile)) { $data = file_get_contents($cacheFile); } else { // 没有缓存且请求失败,返回错误信息 $data = json_encode(['error' => 'Failed to fetch data from API and no cache available']); } } } // 设置响应头,返回JSON header('Content-Type: application/json'); echo $data; ?>
关键细节解释
- 缓存目录权限:要确保服务器对
./cache目录有写入权限,一般设置为0755就可以。如果权限有问题,PHP会报错无法创建文件/目录。 - CURL替代file_get_contents:很多服务器会禁用
allow_url_fopen,导致file_get_contents无法请求远程URL,用CURL兼容性更好。 - 并发写入保护:用
LOCK_EX参数调用file_put_contents,可以避免多个请求同时写入缓存文件导致的损坏。 - 容错处理:如果API请求失败(比如网络问题、API限流),会自动使用旧缓存,保证前端能拿到数据而不是空白错误。
如何在HTML页面调用
你可以用JavaScript的fetch API来请求这个PHP脚本,拿到JSON数据后渲染页面:
<script> fetch('fetch-api-cache.php') .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { // 这里处理你的数据,比如渲染到页面 console.log('获取到的数据:', data); // 示例:把数据显示在页面上 document.getElementById('data-container').textContent = JSON.stringify(data, null, 2); }) .catch(error => { console.error('获取数据出错:', error); }); </script> <pre id="data-container"></pre>
这样设置后,每次前端页面加载时,都会触发这个PHP脚本的逻辑——只有当缓存超过2小时,才会真正去请求远程API,完全不用手动执行更新操作,完美控制请求次数在每日12次以内。
内容的提问来源于stack exchange,提问作者bambadamm
相关产品推荐
相关产品推荐

