ThinkPHP 的页面静态化功能的实现(三)

来源:互联网 发布:什么软件看黄金价格 编辑:程序博客网 时间:2024/05/04 05:43

常说的页面静态化分为两种,一种是伪静态,即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 = "/<a (.*?) href=[\'|\"]\/Index\/articalList\/id\/(.*?)\/p\/(.*?)[\'|\"]>/";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 = '<a '.$value2.' href="/HTML/'.$matchpage[2][0].'_'.$value1.'.html">';$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;                        //返回写入标识[成功/失败]}

不同的网站层级结构和路由规则不一样,所以正则匹配规则也就不一样了,大家可以根据自己的网站的路由规则进行灵活调整改动。


在执行之前,当然要在根目录下的程序入口文件index.php中进行如下配置:

define('HTML_PATH', './HTML/');//生成静态页面的文件位置

(1)网站首页静态化

//首页页面静态化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不同,同时正则匹配规则也就不一样了,大家可以根据自己的网站的路由规则进行灵活调整改动。

2 0
原创粉丝点击