先来看看php在服务器的执行过程:当用户请求服务器php文件的时候,服务器将对php文件进行语法分析,其次是解析,最后才运行。当php文件有内容输出时,该内容会先经过服务器的php的缓冲区(buffer),然后再通过TCP传递到客户端。(buffer其实就是缓冲区,一个内存地址空间,主要用于存储数据区域)

       可见,如果用户直接访问静态页面的时候,服务器的响应时间一般会比访问动态文件的时间短。如果我们能把用户将要访问的动态文件先转化为静态文件即可加快用户访问页面的速度(获取网页的速度)。当然我们要注意静态化的应用场景,页面的静态化主要应用于那些页面内容不经常改动的页面。

       关于静态化,PHP的静态化分为:纯静态和伪静态。其中纯静态又分为:局部纯静态和全部纯静态。这里将的是全部纯静态。

       这里先介绍几个关于PHP缓冲区的相关函数:

ob_start     打开输出控制缓冲(要求php开启缓存,在php配置文件php.ini文件中可以设置 output_buffering = on)

ob_get_contents     返回输出缓冲区内容

ob_clean     清空(擦掉)输出缓冲区

ob_get_clean     得到当前缓冲区的内容并删除当前输出缓冲区

       php生成文件的函数 file_put_contents('文件路径','文件内容')。(当然php中还有其他写文件的方法,如fwrite)

下面有个demo01的案例,目录结构为:

PHP实现页面静态化——全部纯静态化_页面静态化

       我们先来创建一个 mooc_cms 数据库,创建表 news,如下:

PHP实现页面静态化——全部纯静态化_页面静态化_02

       并且插入多条数据,如下:

PHP实现页面静态化——全部纯静态化_html_03

       创建一个数据库的操作类 db.php


<?php 
/**
* 数据库连接封装
*/
class Db {
//存储类的实例的静态成员变量
private static $_instance;
//数据库链接静态变量
private static $_connectSource;
//连接数据库配置
private $_dbConfig = array(
'host' => '127.0.0.1',
'user' => 'root',
'password' => '',
'database' => 'mooc_cms'
);

private function __construct() {

}

/**
* 实例化
*/
public static function getInstance() {
//判断是否被实例化
if(!(self::$_instance instanceof self)) {
self::$_instance = new self();
}
return self::$_instance;
}

/**
* 数据库连接
*/
public function connect() {
if(!self::$_connectSource) {
//数据库连接
// @ 符号可以取消警告提示
self::$_connectSource = @mysql_connect($this->_dbConfig['host'],$this->_dbConfig['user'],$this->_dbConfig['password']);

if(!self::$_connectSource) {
//抛出异常处理
throw new Exception('mysql connect error ');
}
//选择一款数据库
mysql_select_db($this->_dbConfig['database'], self::$_connectSource);
//设置字符编码
mysql_query("set names UTF8", self::$_connectSource);
}

//返回资源链接
return self::$_connectSource;
}
}
?>


       index.php (根据静态文件失效的时间,判断是否重新生成静态文件 index.shtml)


<?php 
//1、连接数据库,然后从数据库里面获取数据
//2、把获取到的数据填充到模板文件里面
//3、需要把动态的页面转化为静态页面,生成纯静态化文件
if(is_file('index.shtml') && (time() - filemtime('index.shtml')) < 300) { //设置缓存失效时间
require_once('index.shtml');
} else {
require_once('db.php');

$connect = Db::getInstance()->connect();
$sql = "SELECT * FROM news WHERE `category_id` = 1 AND `status` = 1 ORDER BY id DESC LIMIT 5";
$result = mysql_query($sql, $connect);
$news = array();
while($row = mysql_fetch_array($result)) {
$news[] = $row;
}
//print_r($news);

ob_start(); //开启缓存区

//引入模板文件
require_once('templates/singwa.php'); //动态文件 singwa.php界面同样进过缓冲区
file_put_contents('index.shtml', ob_get_contents());
/*if(file_put_contents('index.shtml', ob_get_clean())) {
echo 'success';
} else {
echo 'error';
}*/
}

?>

       singwa.php(使用bootstrap框架做界面)


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>新闻中心</title>
<link rel="stylesheet" href="public/css/bootstrap.min.css" type="text/css">
</head>
<body>
<div class="container">
<h3>新闻列表</h3>
<ul class="list-group">
<?php foreach ($news as $key => $value) { ?>
<li class="list-group-item"><a href="#"><?php echo $value['title'];?></a></li>
<?php } ?>
</ul>
</div>
</body>
</html>

       当我们第一次访问 index.php时,服务器将为我们生成一个静态文件index.shtml。

PHP实现页面静态化——全部纯静态化_页面静态化_04

       出现 index.shtml文件:

PHP实现页面静态化——全部纯静态化_静态文件_05

       index.shtml


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>新闻中心</title>
<link rel="stylesheet" href="public/css/bootstrap.min.css" type="text/css">
</head>
<body>
<div class="container">
<h3>新闻列表</h3>
<ul class="list-group">
<li class="list-group-item"><a href="#">今天有一条新闻7</a></li>
<li class="list-group-item"><a href="#">今天有一条新闻6</a></li>
<li class="list-group-item"><a href="#">今天有一条新闻5</a></li>
<li class="list-group-item"><a href="#">今天有一条新闻4</a></li>
<li class="list-group-item"><a href="#">今天有一条新闻3</a></li>
</ul>
</div>
</body>
</html>

       当我们不超过300秒,再次访问index.php时,服务器将访问静态文件index.shtml给我们访问。而当静态文件过期后,我们再次访问index.php,服务器将为我们更新index.shtml静态文件。

       这里讲到的只是一种触发静态文件更新的方法,当然还有:手动触发更新(设置后台管理,管理员想立即更新静态文件,就点击运行生成静态文件即可)、Linux服务器下的crontab定时扫描程序(在Linux服务器下,设置命令:

* /1 * * * * php 路径+文件名    ==>  代表 每一分钟系统将执行一次指定文件

PHP实现页面静态化——全部纯静态化_php_06

文件内容可以为:


require_once('db.php');

$connect = Db::getInstance()->connect();
$sql = "SELECT * FROM news WHERE `category_id` = 1 AND `status` = 1 ORDER BY id DESC LIMIT 5";
$result = mysql_query($sql, $connect);
$news = array();
while($row = mysql_fetch_array($result)) {
$news[] = $row;
}
//print_r($news);

ob_start(); //开启缓存区

//引入模板文件
require_once('templates/singwa.php'); //动态文件 singwa.php界面同样进过缓冲区
file_put_contents('index.shtml', ob_get_contents());