页面静态化技术:就是把一个动态的页面变成一个静态页面,后续用户直接访问静态页面。
页面静态化技术分为两种:真静态和伪静态。
- 真静态:把一个动态的页面,转成一个静态的页面,即.html文件。使用ob缓存技术来实现
- 伪静态:所谓伪静态是从url地址上看是一个静态页面,但是实际上还是对应一个动态页面。使用web服务器的rewrite机制(url的重写机制)来实现。
一、真静态页面的实现
1. ob缓存的介绍
(1) 程序缓存
程序缓存,缓存的数据是,返回给浏览器的数据(包含头信息和主体信息)
程序缓存不能关闭,默认就有的。
(2) ob缓存
ob就是 output_buffering:输出缓存,缓存的数据是返回的响应的主体数据,可以自由的关闭打开。
在请求一个php的过程中,我们实际上经过三个缓存,ob缓存,程序缓存,浏览器缓存。
注意点:如果开辟了ob缓存,主体数据首先存储到ob缓存里面,头信息要存储到程序缓存(无论是否开启ob缓存),当代码执行完毕后,ob缓存里面的数据刷新(移动)到程序缓存,程序缓存再输出到浏览器缓存中,最后输出内容。
(3) 如何开启ob缓存。
方式一:直接在页面中执行ob_start() 函数。
方式二:在php.ini文件中开启。
output_buffering = 容量|on|off
2. ob缓存对应的函数
函数 | 说明 |
ob_start() | 开启 ob缓存,只针对当前页面有效。 |
ob_clean() | 清空ob缓存里面的数据。 |
ob_get_contents() | 获取ob缓存里面的数据内容。 |
ob_end_clean() | 清空ob缓存,并关闭ob缓存。 |
ob_flush() | 把ob缓存里面的数据,给刷新(移动)到程序缓存,并不关闭ob缓存。 |
ob_end_flush() | 把ob缓存里面的数据,刷新(移动)到程序缓存,并关闭ob缓存。 |
3. 真静态实例
给一个生存周期,比如说300秒,过了300秒后,要重新生成静态页面。
如果没有做静态化,并发量是1000,在300秒内,查询数据库多少次。300*1000
如果做了静态化,并发量是1000,而且缓存周期为300秒,在300秒内,查询数据库多少次?仅仅1次。
如何给一个页面设置生命周期。
比如生命周期为300秒,满足什么条件在有效期内。
创建文件的时间戳+生命周期>当前的时间戳
真静态-列表页 list.php
header('content-type:text/html; charset=utf-8'); mysql_connect('localhost','root','123'); mysql_select_db('test'); mysql_query('set names utf8'); $sql = "SELECT id,title,author,content FROM static LIMIT 10"; $res = mysql_query($sql); ?> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>真静态-列表</title> </head> <body> <p>访问时间:<?php echo date('Y-m-d H:i:s') ?></p> <hr> <table> <tr> <td><strong>ID</strong></td> <td><strong>歌曲</strong></td> <td><strong>操作</strong></td> </tr> <?php while ($row = mysql_fetch_assoc($res)) { ?> <tr> <td><?php echo $row['id'] ?></td> <td><?php echo $row['title'] ?></td> <td><a href="show.php?id=<?php echo $row['id'] ?>">详细</a></td> </tr> <?php } ?> </table> </body> </html>
真静态-详情页 show.php
$id = $_GET['id']; $filename = 'show-id-'.$id.'.html'; // 构建生成静态页面的文件名称 // 需要一个生存周期,比如说300秒,过了300秒后,就重新生成静态页面。 if (file_exists($filename) && filemtime($filename)+300>time()) { include $filename; exit(); } header('content-type:text/html; charset=utf-8'); mysql_connect('localhost','root','123'); mysql_select_db('test'); mysql_query('set names utf8'); $sql = "SELECT id,title,author,content FROM static WHERE id = $id"; $res = mysql_query($sql); $info = mysql_fetch_assoc($res); ob_start(); // 开启ob缓存 ?> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>真静态-详情</title> </head> <body> <p>访问时间:<?php echo date('Y-m-d H:i:s') ?></p> <hr> <a href="list.php">返回</a> <h1><?php echo $info['title'] ?></h1> <p><?php echo $info['content'] ?></p> </body> </html> <?php $content = ob_get_contents(); // 获取ob缓存里面的数据内容。 file_put_contents($filename, $content); // 把ob缓存里面的数据内容生成静态html文件
4. 真静态的优缺点
优点: 1. 速度快 2. 安全性高 3. 利于seo
缺点:就是占有磁盘空间., 如果过大,对磁盘响应速度有影响
在什么情况下,建议不要使用真静态
- 页面的数据更新频繁,最好不要使用真静态(比如股票,基金,等实时报价系统)
- 会生成海量页面(比如大型论坛 bbs ,csdn)
- 查询该页面一次后,以后再也不查询该页面.
- 不愿意被搜索引擎抓取的页面.
- 访问量小的页面.
二、伪静态页面的实现
主要是三个配置:
- RewriteEngine on 重写引擎开关,一旦开启,所有的重写条件都生效。
- RewriteCond
- RewriteRule
1. RewriteCond 重写条件
RewriteCond 重写条件,当达到什么条件时,完成重写。
语法为:RewriteCond 判断依据 条件表达式 [条件标志]
判断依据可以使用服务器变量。服务器可以得到一些特定信息
条件表达式,可以为如下形式:
正则或特殊标识:
- -f 表示是一个文件。
- -d 表示是一个目录。
正则,正则表达式字符串。
条件标志:
- [OR] 条件间的或者关系,当出现多个条件时,默认为并且的关系,条件应该是或者的关系下,可以使用OR来表示!
- [NC] 条件不区分大小写。条件匹配时不区分大小写
- [OR,NC]
2. RewriteRule 定义重写规则
RewriteRule 定义重写规则,哪个地址应该被重写到哪个目标地址。
语法:RewriteRule 匹配地址 目标地址 [标识]
匹配的地址:所请求的地址,可使用正则匹配
目标地址:所重写到的地址,可以使用反向引用!$N表示正则匹配到的第N个子模式!
比如:RewriteRule goods-id(d+).html goods.php?id=$1
标志:
- [NC] 不区分大小写
- [QSA] 查询字符串追加,在目标地址已经具有get参数时,会将真实请求的get参数追后边。
3. 伪静态实例
伪静态-列表页 list.php
header('content-type:text/html; charset=utf-8'); mysql_connect('localhost','root','123'); mysql_select_db('test'); mysql_query('set names utf8'); $sql = "SELECT id,title,author,content FROM songs LIMIT 10"; $res = mysql_query($sql); ?> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>伪静态-列表</title> </head> <body> <p>访问时间:<?php echo date('Y-m-d H:i:s') ?></p> <hr> <table> <tr> <td><strong>ID</strong></td> <td><strong>歌曲</strong></td> <td><strong>操作</strong></td> </tr> <?php while ($row = mysql_fetch_assoc($res)) { ?> <tr> <td><?php echo $row['id'] ?></td> <td><?php echo $row['title'] ?></td> <td><a href="show-id-<?php echo $row['id'] ?>.html">详细</a></td> </tr> <?php } ?> </table> </body> </html>
伪静态-详情页 show.php
$id = $_GET['id']; header('content-type:text/html; charset=utf-8'); mysql_connect('localhost','root','123'); mysql_select_db('test'); mysql_query('set names utf8'); $sql = "SELECT id,title,author,content FROM songs WHERE id = $id"; $res = mysql_query($sql); $info = mysql_fetch_assoc($res); ?> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>真静态-详情</title> </head> <body> <p>访问时间:<?php echo date('Y-m-d H:i:s') ?></p> <hr> <a href="list.html">返回</a> <h1><?php echo $info['title'] ?></h1> <p><?php echo $info['content'] ?></p> </body> </html>
.htaccess 文件
<IfModule rewrite_module> RewriteEngine on RewriteCond %{REQUSET_FILENAME} !-f [NC] RewriteRule list.html list.php RewriteRule show-id-(d+).html show.php?id=$1 </IfModule>
4. [QSA]
[QSA]查询字符串追加,在目标地址已经具有get参数时,会将真实请求的get参数追后边。