我正在帮助一个朋友为他的一个脚本编写一个比较合理的缓存函数。它实际上使用9个不同的sql查询来获取排行榜数据(其中一个非常麻烦)
我想到了为它创建一个缓存的想法,从这样开始:

  // Cache directory
  $cacheDir = "/cache";

  // Path to cache directory
  $cachePath = "/var/www/html/test";

  // Better safe than sorry
  if (!file_exists($cachePath . $cacheDir))
  {
        mkdir($cachePath . $cacheDir, 0777, true);
  }

  // Cache rebuild switches
  $monsterCache = false;
  $pvpCache = false;
  $guildCache = false;

  // Get the size and all files within the cache directory
  $cache = array_slice(scandir($cachePath . $cacheDir), 2);
  $cacheSize = sizeof($cache);

继续,我设置了一些开关来确定是否需要更新,然后获取包含缓存文件夹中所有文件的所有文件和数组的大小。
我接着说:
  // Validate the cached files
  if ($cacheSize < 1) {
    // None present. Rebuild all.
    $monsterCache = true;
    $pvpCache = true;
    $guildCache = true;
  } else {
    for ($i = 0; $i < $cacheSize; $i++) {
      // Check the monster kill cache
      if (preg_match('/^[0-9]+_monster_kills_leaderboard\.php/', $cache[$i], $cacheFile)) {
        if (time() >= explode('_', $cacheFile[0])[0]) {
          unlink($cachePath . $cacheDir . "/{$cache[$i]}");
          $monsterCache = true;
        }
      } else {
        $monsterCache = true;
      }

      // Check the PVP cache
      if (preg_match('/^[0-9]+_pvp_leaderboard\.php/', $cache[$i], $cacheFile)) {
        if (time() >= explode('_', $cacheFile[0])[0]) {
          unlink($cachePath . $cacheDir . "/{$cache[$i]}");
          $pvpCache = true;
        }
      } else {
        $pvpCache = true;
      }

      // Check the Castle Guild leader cache
      if (preg_match('/^[0-9]+_guild_leader\.php/', $cache[$i], $cacheFile)) {
        if (time() >= explode('_', $cacheFile[0])[0]) {
          unlink($cachePath . $cacheDir . "/{$cache[$i]}");
          $guildCache = true;
        }
      } else {
        $guildCache = true;
      }
    }
  }

我要做的是在创建和写入缓存文件时,附加一个unix时间戳来表示它有效的时间,将其从文件名中分割出来,并将当前时间与时间戳的时间进行比较,以确定是否删除该文件并重新创建它。(timestamp_pvp_leaderboard.php)
我正在给这些文件写信,就像这样:
  if ($monsterCache) {
    $monsterCache = false;

    // This decides how long the cache is valid
    // Updates every hour from initialization.
    $cacheTTL = strtotime('+1 Hour', time());

    // Fetch the monster data
    <snip>

    // Construct data
    $data = array(
      'Name, Kills' => $result[0]->__get("name") . ', ' . $result[0]->__get("kills"),
      'Name, Kills' => $result[1]->__get("name") . ', ' . $result[1]->__get("kills"),
      'Name, Kills' => $result[2]->__get("name") . ', ' . $result[2]->__get("kills")
    );

    // Populate the cache
    foreach($data as $key => $val) {
      file_put_contents($cachePath . $cacheDir . "/{$cacheTTL}_monster_kills_leaderboard.php", $key.', '.$val.PHP_EOL, FILE_APPEND | LOCK_EX);
    }
  }

这在我的电脑上运行得很好,使用多个浏览器在页面上进行垃圾邮件刷新,但是第二个东西接触到缓存文件(比如第一次读取它,或者在脚本运行时打开它),文件本身就会被垃圾邮件添加。这是相同的3个字段重复本身。
到目前为止,我已经尝试了几种不同的方法,但我绝对搞不清到底发生了什么。
以前有人遇到过吗?你是怎么解决的?
我在这里做错了什么或错过了什么?
今天晚些时候我会继续看,但还是要提前感谢你的洞察!不幸的是,我已经有一段时间没有涉足php了。

最佳答案

我认为您可以尝试使用任何现有的缓存系统,例如apc。它允许您设置(使用所需的ttl)并获取大部分数据。它非常可靠,使用方便。

10-07 15:01