常说的页面静态化分为两种,一种是伪静态,即url 重写,一种是真静态化。
前两篇讲了两种静态化方法,基本都是使用TP自带的静态化机制。但TP写的网站页面路由都比较繁琐复杂,不利于引擎优化。
前段时间做了个网站,由于网站层次太深,在进行SEO优化的时候,不好收录,无奈之下只得自己重新写方法进行页面静态化,采用的方法就是:在后台对每个栏目和内容手动点击进行静态化。后台添加栏目和文章之后手动点击生成静态页面文件。
原理就是:每一个栏目或者内容都唯一的URL路径,根据链接将内容提取出来,然后重新保存文件就是静态化之后的文件。页面中原有的a标签带有的链接,都通过正则表达式匹配之后,重新替换,以保证在一个静态页面中点击链接跳转到的下一个页面也是HTML/目录下的静态化页面。
先将自己写的方法贴出来,参数分别为(栏目或内容的URL路径,静态文件保存路径,生成静态文件的文件名):
function createHtml($url,$dir,$filename){
$content = file_get_contents($url); //获取内容
if (!is_dir($dir)){ //如果目录不存在
mkdir(iconv("UTF-8", "GBK", $dir),0777,true); //创建目录(777权限)
}
//-------------------------------------------处理导航链接-------------------------
$listurls = "/[\'|\"]\/App\/Index\/articalList\/id\/(.*?)[\'|\"]/";
preg_match_all($listurls,$content,$matchlist);
foreach ( $matchlist[1] as $key => $value ) {
$value = trim($value);
$map['catdir'] = $value;
$cat = M('cms_cate')->where($map)->limit(1)->find();
if($cat['lv'] == 1){
$listurl = "\"/HTML/".$value.".html\"";
}else if(!empty($cat['pid']) && ($cat['lv'] == 2)){
$pid = $cat['pid'];
$tmap['id']=$pid;
$pcat = M('cms_cate')->where($tmap)->limit(1)->find();
$pcatdir = $pcat['catdir'];
$listurl = "\"/HTML/".$pcatdir."/".$value.".html\"";
}
$content = str_replace ( $matchlist[0][$key], $listurl, $content );
}
//-----------------------------------------------------------------------------------
//------------------------------------处理文章列表页---------------------------------
//列表页链接进入内容页
$infourl = "/href=[\'|\"]\/App\/Index\/articalInfo\/id\/(.*?)[\'|\"]/";
preg_match_all($infourl,$content,$matchlist);
foreach($matchlist[1] as $key => $value){
$value = trim($value);
$map['id'] = $value;
$cateid = M('Artical')->where($map)->limit(1)->getField('cateid');
$cat = M('cms_cate')->where('id=' . $cateid)->limit(1)->find();
if($cat['lv'] == 1){
$info = "href='/HTML/".$cat['catdir']."/".$value.".html'";
}else if(!empty($cat['pid']) && ($cat['lv'] == 2)){
$pid = $cat['pid'];
$tmap['id']=$pid;
$pcat = M('cms_cate')->where($tmap)->limit(1)->find();
$pcatdir = $pcat['catdir'];
$info = "href='/HTML/".$pcatdir."/".$cat['catdir']."/".$value.".html'";
}
$content = str_replace ( $matchlist[0][$key], $info, $content );
}
//文章列表分页
$page = "//";
preg_match_all($page,$content,$matchpage);
foreach ( $matchpage[3] as $key1 => $value1 ) {
foreach ( $matchpage[1] as $key2 => $value2 ) {
if($key1 == $key2){
$value1 = trim($value1);
$value2 = trim($value2);
$url = '';
$content = str_replace ( $matchpage[0][$key1], $url, $content );
}
}
}
//-----------------------------------------------------------------------------------
//生成的文件路径与文件名
$path = $dir."/".$filename.".html";
if(file_exists($path)){
unlink($path); //删除已有的同名文件
}
//'w' 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
$fp = fopen($path, "w");
$flag = fwrite($fp, $content); //写入内容
fclose($fp);
return $flag; //返回写入标识[成功/失败]
}
不同的网站层级结构和路由规则不一样,所以正则匹配规则也就不一样了,大家可以根据自己的网站的路由规则进行灵活调整改动。
define('HTML_PATH', './HTML/');//生成静态页面的文件位置
//首页页面静态化
public function setindexhtml(){
$host = I("server.HTTP_HOST");
$url = 'http://'.$host.'/index.php';
$dir = './'; //存放路径
$filename = 'index'; //分类名当文件名
$res = createHtml($url,$dir,$filename);
if($res){
$this->ajaxReturn(array("status"=>"1","msg"=>"操作成功"));
}else{
$this->ajaxReturn(array("status"=>"0","msg"=>"操作失败"));
}
}
将首页静态化之后生成的index.html文件保存在网站的根目录下,在服务器端设置程序入口文件为index.html,如下图:
这时候一访问域名,其实就是访问的根目录下的index.html静态文件。而且首页里边a标签跳转到其他页面的链接也都被替换了,点击跳转都会路由到HTML/目录下,寻找对应要跳转的文件名。
(2)文章列表页静态化
//列表页面静态化
public function sethtml(){
$_G = F('f_data');
$id = I("get.id");
$m = M('cms_cate');
if (!$id) {
$info['status'] = 0;
$info['msg'] = 'ID不能为空!';
$this->ajaxReturn($info);
}
$catdir = trim($id);
$map['catdir']=$catdir;
$cat = $m->where($map)->limit(1)->find();
if (empty($cat)) {
$info['status'] = 0;
$info['msg'] = '操作失败,请检查此分类!';
$this->ajaxReturn($info);
}
$psize = $_G['pagesize']['svalue']; //每个分页展示几条数据
$tmap['cateid'] = $cat['id'];
$tmap['status'] = 1;
if($cat['model'] == 'artical'){
$count = M('artical')->where($tmap)->count();//当前分类下文章总数
}else if($cat['model'] == 'product'){
$count = M('product')->where($tmap)->count();
}
$pagecount = ceil(intval($count)/intval($psize)); //分页数(向上取整)
$host = I("server.HTTP_HOST");
//多页面,列表分页
if($pagecount > 1){
for($i=1;$i<=$pagecount;$i++){
$url = 'http://'.$host.'/App/Index/articalList/id/'.$catdir.'/p/'.$i.'';
if($cat['lv'] == 1){
$dir = './HTML/'; //存放路径
}else if(!empty($cat['pid']) && ($cat['lv'] == 2)){ //当前类有父级分类
$pid = $cat['pid'];
$tmap['id']=$pid;
$pcat = $m->where($tmap)->limit(1)->find();
$pcatdir = $pcat['catdir'];
$dir = './HTML/'.$pcatdir; //存放路径
}
$filename = $catdir.'_'.$i; //分类名[当前文件名]
$res = createHtml($url,$dir,$filename);//创建静态文件
if(!$res){
$this->ajaxReturn(array("status"=>"0","msg"=>"操作失败"));exit();
}
}
}
//单页面
$url = 'http://'.$host.'/App/Index/articalList/id/'.$catdir.'';
if($cat['lv'] == 1){
$dir = './HTML/'; //存放路径
}else if(!empty($cat['pid']) && ($cat['lv'] == 2)){
$pid = $cat['pid'];
$tmap['id']=$pid;
$pcat = $m->where($tmap)->limit(1)->find();
$pcatdir = $pcat['catdir'];
$dir = './HTML/'.$pcatdir; //存放路径
}
$filename = $catdir; //分类名当文件名
$res = createHtml($url,$dir,$filename);
if($res){
$this->ajaxReturn(array("status"=>"1","msg"=>"静态页面创建成功"));
}else{
$this->ajaxReturn(array("status"=>"0","msg"=>"操作失败"));
}
}
列表页静态化的难点就在于分页,根据不同分页链接中的p参数的不同进行静态化,在判断当前有几个分页之后,如果只有一个页面就生成一个文件,如果有多个就循环执行生成多个文件。如下图:
(3)文章内容页面静态化
//内容页面静态化
public function sethtml(){
$id = I("get.id");
if (!$id) {
$info['status'] = 0;
$info['msg'] = 'ID不能为空!';
$this->ajaxReturn($info);
}
$map['id'] = $id;
$cateid = M('Artical')->where($map)->limit(1)->getField('cateid');
$cat = M('cms_cate')->where('id=' . $cateid)->limit(1)->find();
if (empty($cat)) {
$info['status'] = 0;
$info['msg'] = '操作失败,请检查此分类!';
$this->ajaxReturn($info);
}
if($cat['lv'] == 1){
$dir = './HTML/'.$cat['catdir']; //存放路径
}else if(!empty($cat['pid']) && ($cat['lv'] == 2)){
$pid = $cat['pid'];
$tmap['id']=$pid;
$pcat = M('cms_cate')->where($tmap)->limit(1)->find();
$pcatdir = $pcat['catdir'];
$dir = './HTML/'.$pcatdir.'/'.$cat['catdir']; //存放路径
}
$host = I("server.HTTP_HOST");
$url = 'http://'.$host.'/App/Index/articalInfo/id/'.$id.'';
$filename = $id; //ID当文件名
$res = createHtml($url,$dir,$filename);
if($res){
$this->ajaxReturn(array("status"=>"1","msg"=>"静态页面创建成功"));
}else{
$this->ajaxReturn(array("status"=>"0","msg"=>"操作失败"));
}
}
后台每添加一篇文章,都手动进行静态化一次,就会在HTML/目录下先生成文章所在的分类目录,然后以文章ID为名生成HTML文件。比如某一篇新闻文章id为32,新闻在news栏目下,就会在HTML/news/目录下生成32.html。
(4)一键静态化当前分类下所有文章内容页页面
//一键静态化当前分类下所有文章内容页页面
public function sethtmlall(){
C('DEFAULT_THEME','App/default/');
$data = I('get.');
$cateid = $data['cateid'];
$map['cateid'] = $cateid;
$map['status'] = 1;
$artical = M('Artical')->where($map)->select();
$cat = M('cms_cate')->where('id=' . $cateid)->limit(1)->find();
if (empty($cat)) {
$info['status'] = 0;
$info['msg'] = '操作失败,请检查此分类!';
$this->ajaxReturn($info);
}
$host = I("server.HTTP_HOST");
foreach($artical as $key => $value){
$url = 'http://'.$host.'/App/Index/articalInfo/id/'.$value['id'].'';
if($cat['lv'] == 1){
$dir = './HTML/'.$cat['catdir']; //存放路径
}else if(!empty($cat['pid']) && ($cat['lv'] == 2)){
$pid = $cat['pid'];
$tmap['id']=$pid;
$pcat = M('cms_cate')->where($tmap)->limit(1)->find();
$pcatdir = $pcat['catdir'];
$dir = './HTML/'.$pcatdir.'/'.$cat['catdir']; //存放路径
}
$filename = $value['id'];
$res = createHtml($url,$dir,$filename); //创建静态文件
if(!$res){
$this->ajaxReturn(array("status"=>"0","msg"=>"操作失败"));exit();
}
}
$this->ajaxReturn(array("status"=>"1","msg"=>"静态页面创建成功"));
}
比如新闻栏目下有很多条文章,一条条手动静态化太慢,可以实现一键静态化。先在数据库中查找新闻文章,然后循环遍历进行静态化,就会在HTML/news/目录下生成所有的新闻文章静态页面。如下图:
此时再访问网站,访问的全部是静态化的页面,访问的URL也会变为自定义的,简化了网站的层级,便于引擎优化。
静态化案例:
静态化之前:http://www.anumuying.com/index.php
静态化之后:http://www.anumuying.com
不同的网站层级结构和路由规则不一样,所以URL不同,同时正则匹配规则也就不一样了,大家可以根据自己的网站的路由规则进行灵活调整改动。