【问题标题】:What is the best way to cache files in php?在 php 中缓存文件的最佳方法是什么?
【发布时间】:2009-07-08 14:20:47
【问题描述】:

我在我的 php 代码中使用 Smarty,我喜欢缓存一些网站页面,所以我使用了以下代码:

// TOP of script
ob_start();   // start the output buffer
$cachefile ="cache/cachefile.html";
// normal PHP script 
$smarty->display('somefile.tpl.html') ;
$fp = fopen($cachefile, 'w'); // open the cache file for writing
fwrite($fp, ob_get_contents()); // save the contents of output buffer to the file
fclose($fp); // close the file
ob_end_flush(); // Send the output to the browser

但是当我在 php 文件末尾打印 ob_get_contents() 时,它是空的!实际上创建的缓存文件也是空的!那么当我使用 smarty 时如何在 php 中缓存文件我知道我可以使用 smarty 缓存,但由于某种原因它对我不起作用。

另外请给我有关 APC 缓存的信息。如何使用它?在我的情况下是否值得使用,我认为它只是用于缓存数据库查询,我阅读了关于它的 php 手册,但我什么也得不到:) 坦克。

【问题讨论】:

    标签: php caching smarty buffering


    【解决方案1】:

    我已将文档(位于here)中的一些代码混合在一起,以获得更完整的 smarty 缓存示例。另外,我不确定您在示例中使用的是什么,但您应该使用 smarty 的方法来操作缓存。

        require('Smarty.class.php');
        $smarty = new Smarty;
    
        // 1 Means use the cache time defined in this file, 
        // 2 means use cache time defined in the cache itself
        $smarty->caching = 2; 
    
        // set the cache_lifetime for index.tpl to 5 minutes
        $smarty->cache_lifetime = 300;
    
        // Check if a cache exists for this file, if one doesn't exist assign variables etc
        if(!$smarty->is_cached('index.tpl')) {
            $contents = get_database_contents();
            $smarty->assign($contents);
        }
    
        // Display the output of index.tpl, will be from cache if one exists
        $smarty->display('index.tpl');
    
        // set the cache_lifetime for home.tpl to 1 hour
        $smarty->cache_lifetime = 3600;
    
        // Check if a cache exists for this file, if one doesn't exist assign variables etc
        if(!$smarty->is_cached('home.tpl')) {
            $contents = get_database_contents();
            $smarty->assign($contents);
        }
    
        // Display the output of index.tpl, will be from cache if one exists
        $smarty->display('home.tpl');
    

    至于 APC 缓存,它的工作方式与 smarty 相同。它们都将数据存储在文件中一段特定的时间。每次您希望访问数据时,它都会检查缓存是否有效,如果有效则返回缓存值。

    但是,如果不使用 smarty,您可以像这样使用 APC:
    此示例将数据库查询的结果存储在缓存中,类似地,您可以修改它以存储整个页面输出,这样您就不必经常运行昂贵的 PHP 函数。

    // A class to make APC management easier
    class CacheManager  
    {  
         public function get($key)  
         {  
              return apc_fetch($key);  
         }  
    
         public function store($key, $data, $ttl)  
         {  
              return apc_store($key, $data, $ttl);  
         }  
    
         public function delete($key)  
         {  
              return apc_delete($key);  
         }  
    }  
    

    结合一些逻辑,

    function getNews()  
    {  
         $query_string = 'SELECT * FROM news ORDER BY date_created DESC limit 5';  
    
         // see if this is cached first...  
         if($data = CacheManager::get(md5($query_string)))  
         {  
                 // It was stored, return the value
              $result = $data;  
         }  
         else  
         {  
                 // It wasn't stored, so run the query
              $result = mysql_query($query_string, $link);  
              $resultsArray = array();  
    
              while($line = mysql_fetch_object($result))  
              {  
                   $resultsArray[] = $line;  
              }  
    
                 // Save the result inside the cache for 3600 seconds
              CacheManager::set(md5($query_string), $resultsArray, 3600);  
         }  
    
         // Continue on with more functions if necessary 
    }  
    

    这个例子是从here稍微修改的。

    【讨论】:

    • @lan Elliott 是的,Smarty 缓存是个好主意,但我不能使用它。因为我只有一个 $smarty->display('index.tpl') ;和 news.tpl 等其他页面像这样进入我的 index.tpl 中心 {include file=$page_center} 然后在 news.php 文件中我使用这一行 $smarty->assign('page_center' , 'news.tpl ');但是当我启用缓存时,它仍然向我显示页面中心的默认内容而不是 news.tpl 但是当我关闭缓存时它工作正常。
    • @mehdi 听起来您需要使用自定义缓存 ID - 允许您缓存任意多个版本的 index.tpl。例如在news.php 中,您可以调用$smarty->display('index.tpl', 'news|' . $article_id); 对于帮助页面,您可以使用'help|' . $topic 等的缓存ID。(使用管道字符来构建缓存ID 允许您有选择地清除缓存 - 例如清除所有新闻文章。)
    【解决方案2】:

    你的意思是你在调用 ob_end_flush() 之后再次调用 ob_get_contents() 吗?如果是这样,您写入文件的内容将从 PHP 的内存中“删除”。

    如果您仍希望输出 HTML,请先将 ob_end_flush 保存到变量中,然后将其传递给 fwrite。您可以稍后在页面下方使用该变量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-19
      • 2010-09-07
      • 1970-01-01
      • 2021-06-26
      • 2022-01-11
      • 2011-01-13
      • 2014-06-19
      • 1970-01-01
      相关资源
      最近更新 更多