【问题标题】:What is the best way to do server-side output caching in PHP?在 PHP 中进行服务器端输出缓存的最佳方法是什么?
【发布时间】:2011-01-13 09:54:48
【问题描述】:

我现在有一个相当复杂的index.php,我只想每小时运行一次。实现这一目标的最佳方法是什么?我的一些想法

  • apc_store($page, 60*60*) 将其放入 APC - 我觉得这不是 APC 的用途,而且可能会对我网站的其他部分造成不良影响
  • 将输出保存到某个文件系统 - 然后 apache 需要在某个地方进行写访问,这可能会很痛苦
  • 不知何故设置 apache 为我做缓存 - 这可能吗?

【问题讨论】:

  • 我已经看到 APC 正是用于此目的,我不认为这很糟糕。

标签: php apache caching indexing apc


【解决方案1】:

你真的应该看看Memcached(优秀的php支持。)

另一个不错的选择是设置Squid Cache Server

【讨论】:

  • 两者都需要额外的依赖。对于这个用例,我不知道这是否有必要......
【解决方案2】:

提供静态页面始终是最优化的方式。因此,例如使用 Cron 或您选择的任何其他计划服务,每小时生成一次索引的静态版本,并将其写入文件,例如 index.html。如果您仍然需要索引上的一些动态部分,您甚至可以让它生成为 .php。

我会说这绝对是最好的方法。当然,处理文件的 chmod 设置会有些小麻烦,但这并不是什么大问题。

【讨论】:

    【解决方案3】:

    将页面保存到静态文件中并使用 .htaccess 规则来提供静态页面。

    我不确定具体细节,但我认为 drupal 的 codeignitor 和 boost 可以做到这一点。

    【讨论】:

      【解决方案4】:
      1. 当访问者点击您的页面时,生成内容,将其发送给用户并将静态文件保存在磁盘的某个位置。
      2. 当下一个访问者来时,首先查找保存的文件,如果存在,则提供该文件,而不是执行 index.php 文件中的所有代码。 一个基本的例子是

        if (file_exists($cacheFileName))
        {
            require $cacheFileName;
            exit;
        }
        
        // here goes the rest of your index.php code
        //..
        
        // assuming your output is buffered and is contained in $output:
        echo $output;
        
        $cacheFileName = '/path/to/your/file.inc';
        file_put_contents($cacheFileName, $output);
        
      3. 设置将删除的 cron 作业 您从磁盘保存的缓存文件 每小时或您需要的频率 到。或者,在您的 index.php 中,在每个页面命中检查缓存文件是多久之前创建的,如果它的存在时间比您希望的要长,则生成一个新的缓存文件。不过,cron 作业更容易设置。

      不过,要回答这个深刻的哲学问题,如果您不想依赖第三方缓存解决方案,将生成的输出保存到单独的文件中的磁盘可能是最好的方法。 APC 非常适合缓存将在需要时重新生成页面的代码,如果我们谈论的是小型(ish)应用程序,memcached 绝对是矫枉过正。

      【讨论】:

      • 谢谢。为什么磁盘存储比 APC 更好?
      • 我不会说一个比另一个更好,我会将它们用于不同的目的。当您有一个复杂的应用程序并且您需要: 1) 加速 PHP; 2)缓存一些生成成本高的用户值。例如,我不知道系统上所有可用文件的列表,用于 __autoload() 函数或任何其他占用大量资源来构建且不是用户特定的变量,因此您可以安全地缓存它。我不会在 APC 中丢弃生成的页面输出,这不是它的用途。
      • 谢谢。将其放入 APC 的确切缺点是什么?我不必摆弄文件权限,也不会有任何东西弄乱我的磁盘(仅在内存存储中)。
      • 我只是不明白将 HTML 代码放入 APC 的意义。 APC 是 PHP 的操作码缓存,它不会比包含磁盘中的文件更快地提供预生成的 HTML - 它没有什么可以加快速度,因为(我假设)生成的输出中没有 PHP。在您的问题中,您说“我觉得这不是 APC 的用途”。我也是这样的感觉:)。
      • 我对此略有不同。我给了你一个赞成票并接受了我的回答。希望这是一个很好的妥协:)
      【解决方案5】:

      我在 Rowlf 和 jamietelin 的基础上稍作改动 回答。

      创建 3 个文件:

      index.html

      <meta http-equiv="refresh" content="0;url=/index_update.php" />
      

      index.php

      <?php // do all your normal stuff ?>
      

      index_update.php

      <?php
      
      $file = "index.html";
      $time = 60 * 10 - (time() - filemtime($file));
      
      # this is on the first install 
      if (filemtime($file) != filectime($file))
          $time = 0;
      
      if ($time > 0) {
          die("Data was already updated in the 10 minutes. Please wait another " . ($time) . " seconds.");
      }
      
      ob_start();
      require "index.php";
      $data = ob_get_contents();
      
      $fp = fopen($file, "w");
      fwrite($fp, $data);
      fclose($fp);
      
      header("Location: /");
      

      然后是一个 cronjob:

      */15 * * * * curl http://example.com/index_update.php
      

      因此,如果有人在生产推送后偶然发现该页面,他们只会透明地为您创建一个新的 index.html,否则,您的 cronjob 将每 15 分钟创建一次。

      只要确保 index.html 可被您的 apache 服务器写入。如果这听起来很可怕,那么只需让您的 cronjob 以另一个对 index.html 具有写入权限的用户身份运行 php index_update.php。不过,您将无法访问所有 apache 环境。

      希望对你有帮助,欢迎 cmets。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-16
        • 1970-01-01
        • 2011-01-18
        • 2010-09-09
        • 1970-01-01
        • 1970-01-01
        • 2011-09-30
        • 2016-10-27
        相关资源
        最近更新 更多