PHP实现文件缓存

有很多不同的方法实现缓存,但是最简单的方式(可能不是最高效的)就是在你的PHP脚本中添加几行代码。

输出缓存

在PHP中,如果你在程序的开头调用 ob_start()这个方法,它会禁止所有的输出,直到你明确的刷新(flush)输出缓冲。

一个简单的缓存的例子

让我们看一个最基础的缓存的例子(也许很少有人这样用),这段脚本会在你访问home.php这个页面时将内容保存到缓存文件home.html中。


<?php
// start the output buffer
ob_start(); 

//你的其他的php脚本和html

$cachefile = "cache/home.html";
// open the cache file "cache/home.html" for writing
$fp = fopen($cachefile, 'w'); 
// save the contents of output buffer to the file
fwrite($fp, ob_get_contents()); 
// close the file
fclose($fp); 
// Send the output to the browser
ob_end_flush(); 
?>

这似乎不是很有用,因为每次运行上面的脚本都只能够生成一个home.html文件。但是这是缓存的基础,它将PHP脚本生成的内容保存到了一个文件中。当你访问home.html时,你将会发现home.html和你访问这个PHP脚本时生成的内容是一样的。

使用缓存文件

现在我们已经知道怎样通过PHP代码生成了一个缓存文件,我们需要找到一种使用这些文件的方法。如果用户请求了一个之前没有人请求过的页面,或者上一次请求发生了很久,缓存文件已经过时了,这种情况下,PHP脚本需要重新查询数据库或其他资源来生成一个新的缓存文件。 如果用户请求的页面最近已经有人请求过,而且请求的页面在缓存中,PHP脚本只需要将这个缓存文件传递给用户,而不需要做其他的处理。
 
检查一个页面是否已经缓存了的方法很简单:
 
<?php

$cachefile = "cache/home.html";

if (file_exists($cachefile)) {


	// the page has been cached from an earlier request

	// output the contents of the cache file

	include($cachefile); 


	// exit the script, so that the rest isnt executed
	exit;

}


?>

将上面的这段代码放在PHP脚本的开头,这样程序运行的时候,首先会检查缓存文件是否存在,如果存在就使用缓存文件,然后就跳出(exit)这段脚本(这就是说,这段代码以下的内容就不会执行了)。如果你的网站内容从来不需要改变,以上脚本就足够了;但是很少有网站从来不修改页面内容。
 
如果你有一个网站,它每天只需更新一次,那么,你可以使用计划任务(cron)每天清空一次缓存目录。这可能不适用与很多网站,我们需要一种使缓存内容过期的方法,能够确定什么时候不再使用缓存。

缓存数据过期
有很多种方法来检测一个缓存文件是否需要被更新。下面我们介绍两种最常用的方法。

简单的时间过期
对于大多数网站而言,这可能是最好的选择,你(程序员)会给缓存文件设置一个存活周期,例如5分钟,20分钟,1个小时等。当缓存文件过了存活期它们就会过期,然后重新生成一个缓存文件。下面的例子假设缓存文件的存活周期为2个小时。用户第一次来访是在12:00,由于没有缓存文件,所以会生成缓存文件,它将会在14:00过期。这就是说,即使数据库(生成页面的内容)在13:20时被更新了,在这期间及14:00以前,用户看到的都是缓存文件中的内容。14:00以后的第一次请求发生时,PHP才会查询数据库,浏览者将会看到13:20更新的信息。

 
为了实现这种效果我们只需要扩展以下代码:
if (file_exists($cachefile))
在上面脚本前,添加一段代码,检测缓存文件修改时间及是否过期.
<?php 

		 // 5 minutes

        $cachetime = 5 * 60; 

        // Serve from the cache if it is younger than $cachetime

        if (file_exists($cachefile) && 
           (time() - $cachetime < filemtime($cachefile))) 
        {


        	include($cachefile);

        	echo "<!-- From cache generated ".date('H:i', 
           filemtime($cachefile))." 
        	-->n";


        	exit;

        }


?>


下面是完整的例子,它会每五分钟更新一次缓存文件。

<?php

      $cachefile = "cache/".$reqfilename.".html";


      $cachetime = 5 * 60; // 5 minutes


      // Serve from the cache if it is younger than $cachetime

      if (file_exists($cachefile) && (time() - $cachetime
         < filemtime($cachefile))) 
      {

         include($cachefile);


         echo "<!-- Cached ".date('jS F Y H:i', filemtime($cachefile))." 
         -->n";


         exit;

      }

      ob_start(); // start the output buffer


//.. Your usual PHP script and HTML here ...


       // open the cache file for writing
       $fp = fopen($cachefile, 'w'); 


       // save the contents of output buffer to the file
	    fwrite($fp, ob_get_contents());

		// close the file

        fclose($fp); 

		// Send the output to the browser
        ob_end_flush(); 
?>
 

只有在需要的时候重新生成缓存文件

检测一个缓存文件是否过期的另一种方法是查看数据源是否已经被修改过,这样会稍微增加每次请求的负载(load),因为对于一个基于数据库的网站而言,它需要建立一个到数据库的连接,或者查询文件修改的时间。而且这样做会使得脚本变得稍微复杂一些。然而,这种方法可以避免不必要的大量查询,避免在文件没有任何修改的时候重新生成缓存页面。和前面的例子比较,我们只需要修改脚本的以下部分:
if()

<?php
        $cachefile = "cache/".$reqfilename.".html";


        // Serve from the cache if it is the same age or younger than the last 
        // modification time of the included file (includes/$reqfilename)

        if (file_exists($cachefile) && (filemtime("includes/".$reqfilename)
           < filemtime($cachefile))) {  


           include($cachefile);

           echo "<!-- Cached ".date('H:i', filemtime($cachefile))." 
           -->n";


           exit;
        }


		 // start the output buffer
        ob_start(); 

      

//.. Your usual PHP script and HTML here ...


        // open the cache file for writing

        $fp = fopen($cachefile, 'w');

		 // save the contents of output buffer to the file
        fwrite($fp, ob_get_contents());


		 // close the file
        fclose($fp);

		 // Send the output to the browser
        ob_end_flush();
?>

哪里不能使用缓存
缓存不应该 被用于一些情景下,最明显的一个例子就是:搜索结果,论坛帖子等情况。这些地方,内容需要随着用户的输入返回实时的结果。一般也不建议在“最新资讯”页使用缓存。

posted on 2012-03-03 16:51  IT技术畅销书  阅读(327)  评论(0)    收藏  举报

导航