ThinkPHP 的页面静态化功能的实现(三)
常说的页面静态化分为两种,一种是伪静态,即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静态文件。而且首页里边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"=>"操作失败"));
- }
- }
(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"=>"操作失败"));
- }
- }
(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"=>"静态页面创建成功"));
- }
此时再访问网站,访问的全部是静态化的页面,访问的URL也会变为自定义的,简化了网站的层级,便于引擎优化。
静态化案例:
静态化之前:http://www.anumuying.com/index.php
静态化之后:http://www.anumuying.com
不同的网站层级结构和路由规则不一样,所以URL不同,同时正则匹配规则也就不一样了,大家可以根据自己的网站的路由规则进行灵活调整改动。