用户浏览文章详情,如果每次都从数据库读取会对数据库造成很大的压力,所以讲文章做成 .shtml 的静态页面并限时去更新它是比较好的。用apache的ab压力测试,发送1000次请求,20并发,发现使用下面的生成静态页面方式每秒最大访问量是105,每次请求需要9.5毫秒,而如果不采用这种方式的话每秒最大访问量是50,每次请求需要19.6毫秒,差别是如此之大,说明了生成静态.shtm文件l的重要性
下面说下本人的思路:
1、用户访问的时候判断对应文章的静态页面是否存在,如果不存在生成对应文章的静态页面,并输出静态页面,那么后面的用户继续访问的话就暂时不会再调取数据库了。
2、如果用户访问的对应的文章的静态页面存在,则对静态文件的最后一次修改时间进行判断,看是否过期。如果过期则重新查询数据库生成静态页面,如果没有过期则直接输出静态页面。
主要用到了以下的函数:
判断文件是否存在:file_exists(); 获取文章修改时间:filemtime(); 修改文件内容:file_put_contents(); 读取文件内容:file_get_contents();
打开缓冲区:ob_start(); 清除缓冲区并且获取输出流:ob_get_clean();
下面展示下代码和注释(用的ThiknPHP框架):
<?php
namespace Home\Controller;
use Think\Controller;
class ArticleController extends Controller {
public function index(){
}
/**
* 文章详情页面
* 通过修改时间判断是否要进行重新生成 是测试所以过期时间设置为30秒
*/
public function detail(){
if($articleid = I('articleid')){
$path = 'Public/Home/Article/article'.$articleid.'.shtml';
if(file_exists($path)){
$time = filemtime($path);
//过期了重新生成静态文件
if(($time+30)<time()){
$this->mkDetail($path,$articleid);
}
//不存在文件生成新的
}else{
$this->mkDetail($path,$articleid);
}
//输出模板
$out = file_get_contents($path);
echo $out;
}else{
$this->redirect('Home/Index/index');
}
}
/**
* 生成文章详情页面
* @param $path 静态文件的路径
* @param $articleid 文章的id
*/
private function mkDetail($path,$articleid){
ob_start();
$article = M('article');
$data = $article->find($articleid);
$data['created'] = date('Y-m-d H:i:s',$data['created']);
$this->assign('data',$data);
$this->display('mkDetail');
$out = ob_get_clean();
file_put_contents($path,$out);
}
}
静态页面的代码:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><{$data['title']}>_cms文章详情</title>
<style>
#con{
width: 960px;margin: 0 auto;
}
h1{
text-align: center;font-size: 16px;
}
#info{
text-align: center;
}
</style>
</head>
<body>
<div id = "con">
<h1><{$data['title']}></h1>
<div id = "info">
<{$data['created']}>
</div>
<div id = "content">
<{$data['content']}>
</div>
</div>
</body>
</html>
从列表页访问几篇文章后 查看article下面的目录可以看到静态页面:
如果本人直接在数据库中修改文章的内容,刷新文章详情页面内容是不会改变的,只有在30秒后才会发生改变。说明已经成功。
输出结果: