伪静态页面的制作
我们看到一些网站,地址是以 .htm 或 .html 结尾的,形如 http://www.k810.com/html/guide/2/1.htm 这样的格式,其中有一部分是真的静态页面,有一些侧是伪静态的。
静态和伪静态的网站我都有做过,其中伪静态的制作和维护都容易一些。所以先向大家介绍伪静态的实现方法。我这里介绍的方法并非用 URL Rewrite (URL重写)实现,不用改写复杂的 URL Rewrite 规则,制作维护起来更加简便。
详细的案例请查看 http://www.k810.com/ 。由于像“会员中心”那些页面,需要登录才能访问的,就不做成伪静态了。否则容易暴露该站点的“静态页面”是假的,呵呵。
第一步,Apache 配置。
Apache 配置,要求在 httpd.conf 的 Directory-Options 中添加 MultiViews 支持。例如
<Directory "D:/wwwroot/">
Options Indexes FollowSymLinks MultiViews
## 默认为 Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
先介绍一下实现的原理。假如一个网页的动态地址为 guide.php?page=2&typeid=1 ,对应的伪静态地址为 html/guide/2/1.htm 。
开启了 MultiViews 后,保证的根目录下没有 html/ 目录,然后新建 html.php 文件。访问地址 html/guide/2/1.htm 时,由于 Apache 找不到 html/ 目录,它会读取并用PHP解释 html.php 这个文件。所以我们要在 html.php 中,解读这个伪静态地址为对应的动态地址,然后向用户输出相应的内容。
第二步,创建 html.php 文件。
html.php 的代码及解释:
<?
$parseformat = array();
// 变量格式设定:
// 每个文件允许接受的 GET 变量,以 / 分隔
// 静态地址中,每个值的顺序会与变量名顺序对应
// 建议常用到的变量写在前面,可能不会接收到的变量写在后面
$parseformat['tech.php'] = 'page';
$parseformat['tech_type.php'] = 'typeid/page';
$parseformat['tech_details.php'] = 'id';
$parseformat['guide.php'] = 'page';
$parseformat['guide_details.php'] = 'id';
// SCRIPT_IN_ROOTPATH : 本文件相对 document_root 所在的文件夹(以 / 结尾)
$this_script_path = str_replace('\\','/',dirname(__FILE__)."/");
if(!defined("SCRIPT_IN_ROOTPATH")){
define("SCRIPT_IN_ROOTPATH", substr($this_script_path,strlen($_SERVER['DOCUMENT_ROOT']) ) );
}
// 动态链接解释并规范化,返回一个动态链接对应的静态链接
// 在链接向一个静态页面时需要调用,其中 $link 是一个动态链接的地址,如 xxx.php?typeid=1&page=2
// 返回 html/xxx/1/2.htm 这样的格式
function url($link){
global $parseformat;
//分解 $link 字符串为两部份,以 "?" 号分隔,前面部份是文件路径 $url_file,后面部份是请求字符串 $url_query
$url_file = $url_query = '';
list($url_file,$url_query) = split('\?',$link,2);
//若是以 "/" 开头的绝对路径,则改为相对路径
if($url_file[0]=='/'){
$url_file = substr($url_file,strlen(SCRIPT_IN_ROOTPATH));
}
// 将文件路径 / 替换为 --
$url_file = str_replace('/','--',$url_file);
//去掉文件名中的 ".php" 后缀
$file = substr($url_file,0,-4);
if(!$file) $file = "index";
//将 url_query 的值解释到 $query_values 数组
$query_values = array();
if($url_query) parse_str($url_query,$query_values);
// 该文件的变量格式,分解为数组
$format_arr = array();
if($parseformat["$file.php"]) $format_arr = split('/',$parseformat["$file.php"]);
// 各个变量的值,按照变量名的出现顺序规范排列
$querys = array();
foreach($format_arr as $fa){
$querys[] = $query_values["$fa"];
}
$query = join('/',$querys);
// 去除末尾 / 号
// 为什么会出现末尾的 / 号呢
// xxx.php?typeid=1&page=2 => html/xxx/1/2.htm
// xxx.php?typeid=1 => html/xxx/1/.htm
// 因为有些变量不一定要传值,但设置里面有这个变量,需要给它留一个位置
// 如果这个位置是在最后,就可以去掉了。
if(strrchr($query,'/')=='/'){
$query = preg_replace('/\/+$/mis','',$query);
}
// 返回的链接,加上 .htm 字符。
// 看得出来 .htm 这几个字符其实是多余的,反向解释的时候还要先去掉呢
$htmlfile = SCRIPT_IN_ROOTPATH."html/".$file.($query?"/$query":"").".htm";
return $htmlfile;
}
// 直接访问 html.php, 即用户访问的路径为伪静态地址时:
// 这里是反向解释,把静态链接解释为对应的动态链接;
// 把 html/xxx/1/2.htm 这样的访问格式,解释为 xxx.php?typeid=1&page=2 相同的效果
if(basename($_SERVER['SCRIPT_FILENAME'])==basename(__FILE__)){
list($request_uri,) = split('\?',str_replace('\\','/',$_SERVER['REQUEST_URI']),2); // ?号后的去掉,HTML 的路径是不需要那部份的
// 访问路径,去掉 SCRIPT_IN_ROOTPATH 和 .htm
$uri_string = substr($request_uri,strlen(SCRIPT_IN_ROOTPATH),-4);
// 以 "/" 号为分隔,分解访问路径到数组中
// 第一项值当然是 html,第二项是没有后缀的实际文件路径,其他为各个请求变量对应的值。
$uri_string_arr = split('/',$uri_string);
//文件路径,加回 .php 后缀
$phpfile = str_replace('--','/',$uri_string_arr[1]).".php";
// $_SERVER['PHP_SELF'] 这个系统变量, 用伪静态访问的话,会是 html.php ...
$_SERVER['PHP_SELF'] = SCRIPT_IN_ROOTPATH.$phpfile;
//读取变量的格式,分解为数组
$format_arr = array();
if($parseformat["$phpfile"]) $format_arr = split('/',$parseformat["$phpfile"]);
//静态地址中的变量值,把它们赋值到 $_REQUEST 和 $_GET 对应的变量中:
for($i=0;$i<count($format_arr);$i++){
if(isset($uri_string_arr[$i+2]) && $format_arr[$i]){
$queryvalue = urldecode($uri_string_arr[$i+2]);
if(!isset($_REQUEST["$format_arr[$i]"])) $_REQUEST["$format_arr[$i]"] = $queryvalue;
if(!isset($_GET["$format_arr[$i]"])) $_GET["$format_arr[$i]"] = $queryvalue;
}
}
//include 实际的文件
chdir(dirname($phpfile)) && @include($this_script_path.$phpfile);
}
?>
第三步,包含 html.php 。
其他页面,包括指向 guide.php 的页面和 guide.php 页面本身,只需要以 <? include_once("html.php");?> 开头,再添加其他内容即可。
第四步,添加 BASE HREF 。
由于伪静态页面的路径和动态的不一样,导致浏览器解释到的目录不同,所以需要在 HTML 代码的<HEAD>部分,添加 BASE HREF 标签,代码如
<base href='http://www.k810.com/' />
其中的网址改为你自己的网站地址。
第五步,链接改写。
其中指向伪静态页面的链接,写为类似<?=url("guide.php?page=2&typeid=1");?> 这样的格式,得到标准的伪静态链接。例如
<? include_once("html.php");?>
<html>
<head>
<title>快精灵</title>
<base href='http://www.k810.com/' />
<head>
<body>
<a href="./">首页</a>
<a href="<?=url("guide.php?page=2&typeid=1");?>">设计指南</a>
</body>
</html>
至此,我们的伪静态页面制作完成。添加多个伪静态页面,只要改下程序,并不需要再改写 URL Rewrite 规则,或者虚拟机上多个站点需要制作成伪静态页面,这种方式显得特别简单。
要改回动态的站点,只需要把 html.php 的内容改为 <? function url($link){return $link;} ?> 即可,是不是很方便呢?
我制作了简单的实例供参考,需要的朋友可以点击如下地址下载:
htmldemo_k810.com.rar 转载请注明出处
|