动态页面静态化

什么是静态化?

PHP静态化的简单理解就是使网站生成页面以静态HTML的形式展现在访客面前,PHP静态化分纯静态化和伪静态化,两者的区别在于PHP生成静态页面的处理机制不同。

PHP动态网页静态化分为:纯静态化 和 伪静态化;纯静态化又分为:局部静态化 和 完全静态化

纯静态化:是把PHP生成的动态页面保存成静态的html文件,用户访问该静态页面,而不是用户每一次访问都重新生成一张相同的网页,优点就是减小服务器开销,

  局部静态化:是生成的静态文件中,有局部的数据还是通过ajax技术动态获取的;

  完全静态化:即不存在动态获取数据的情况,所以内容都来自静态的html页面

伪静态化:其实还是动态访问,其实质是动态生成数据,你访问的网址类似于"http://yourhost.com/index/post/12",是一个静态地址,该地址多见于博客地址,
但伪静态化中,你访问的网址实际上经过服务器解析,还是会解析成类似于"http://yourhost.com/?c=index&a=post&id=12"的地址,所以称之为伪静态化   伪静态的优点:美观;便于搜索引擎收录

为什么要静态化?

一、加快页面打开浏览速度,静态页面无需连接数据库打开速度较动态页面有明显提高;
二、有利于搜索引擎优化SEO,Baidu、Google都会优先收录静态页面,不仅被收录的快还收录的全;
三、减轻服务器负担,浏览网页无需调用系统数据库;
四、网站更安全,HTML页面不会受php相关漏洞的影响; 观看一下大一点的网站基本全是静态页面,而且可以减少攻击,防sql注入。
数据库出错时,不影响网站正常访问。
生成html文章虽操作上麻烦些,程序上繁杂些,但为了更利于搜索,为了速度更快些,更安全,这些牺牲还是值得的。

如何实现静态化?

1.使用PHP文件读写功能与ob缓冲机制生成静态页面(记住这是缓冲不是缓存),缓冲缓解了高效CPU和低级I/O的矛盾。

比如某个商品的动态详情页地址是: http://xxx.com?goods.php?gid=112
那么这里我们根据这个地址读取一次这个详情页的内容,然后保存为静态页,下次有人访问这个商品详情页动态地址时,我们可以
直接把已生成好的对应静态内容文件输出出来。在这里ob只是充当了一个媒介,因为文件比较大,所以变量存储不太可行,就用了缓冲作为中间件存储PHP生成好的纯HTML文件而已。

代码实现逻辑:

<!--?php
$gid = $_GET['gid']+0;//商品id
$goods_statis_file = "goods_file_".$gid.".html";//对应静态页文件
$expr = 3600*24*10;//静态文件有效期,十天
if(file_exists($goods_statis_file)){
  $file_ctime =filectime($goods_statis_file);//文件创建时间 
     if($file_ctime+$expr-->time()){//如果没过期
      echo file_get_contents($goods_statis_file);//输出静态文件内容
         exit;
     }else{//如果已过期
         unlink($goods_statis_file);//删除过期的静态页文件
         ob_start();
  
            //从数据库读取数据,并赋值给相关变量
  
            //include ("xxx.html");//加载对应的商品详情页模板
  
            $content = ob_get_contents();//把详情页内容赋值给$content变量
            file_put_contents($goods_statis_file,$content);//写入内容到对应静态文件中
            ob_end_flush();//输出商品详情页信息
     }
}else{
 ob_start();
  
 //从数据库读取数据,并赋值给相关变量
  
 //include ("xxx.html");//加载对应的商品详情页模板
  
 $content = ob_get_contents();//把详情页内容赋值给$content变量
 file_put_contents($goods_statis_file,$content);//写入内容到对应静态文件中
 ob_end_flush();//输出商品详情页信息
  
}
  
?>

2.使用nosql从内存中读取内容(其实这个已经不算静态化了而是缓存);

以memcache为例:(memcached是键值一一对应,key默认最大不能超过128个字节,value默认大小是1M,因此1M大小满足大多数网页大小的存储。)

<!--?php
$gid = $_GET['gid']+0;//商品id
$goods_statis_content = "goods_content_".$gid;//对应键
$expr = 3600*24*10;//有效期,十天
$mem = new Memcache; 
$mem--->connect('memcache_host', 11211);
$mem_goods_content = $mem->get($goods_statis_content);
if($mem_goods_content){
  echo $mem_goods_content;
}else{
 ob_start();
 //从数据库读取数据,并赋值给相关变量
 //include ("xxx.html");//加载对应的商品详情页模板
 $content = ob_get_contents();//把详情页内容赋值给$content变量
 $mem->add($goods_statis_content,$content, false, $expr);
 ob_end_flush();//输出商品详情页信息
}
  
?>

给你个思路,OB在写用户静态化时候这个可以让你每次输出的必定为纯静态HTML:

<?php ob_start();//开启缓存 
?>
<p>我是要生成的静态内容,也可以在该处链接数据库生成动态内容于此</p>
<?php 
file_put_contents( 'index.html', ob_get_clean() );//把生成的静态内容保存到index.html文件,而不是输出到浏览器
?>

更简洁的完整逻辑:

<?php
$file_name = 'index.html';
if(file_exists( $file_name ) &&  filemtime( $file_name ) - time() < 10 ){//如果文件是存在并且最后修改时间小于设定时间 10s
    //filemtime( $file_name );//得到文件最后修改时间
    //time();//当前时间
    require_once( $file_name );//引入文件
}else{
 ob_start( );
 ?>
<p>我是要生成的静态内容</p>
 <?php
file_put_contents( $file_name,  ob_get_contents() )//输出到浏览器
}

现在存在一个问题,我们存入的静态HTML页面是之前某个时间点的数据,如果后台数据存在更新,定时刷新不能及时更改静态页面,怎么办?

所以引入了手动触发的功能????

有两种,一种是在纯静态HTML利用ajax,当输出该HTML页面的时候JavaScript就会发送ajax请求验证当前数据库评论数量(举个栗子)与静态页面上的数量对比如果不一致,就会提示你手动更新,比如:

手动触发的大概样式就类似于优酷视频评论区,当有新评论时,会后一条黄色的小提示框:“有新评论,点击更新”,也类似于app中的下滑刷新的机制,自己去寻找吧。。

自动触发???也是定时????

Linux下的crontab定时扫描程序????

这个不清楚,首先自己的想法是,自动触发其实是改变数据库数据的用户触发,比如,某个用户评论了某篇文章,那么该篇文章对应的静态化HTML就需要更新,所以写一个程序在用户(任何用户)评论该表的时候就会更新存储的静态HTML页面,那么
该页面就实现了自动触发了(如果只有一个人评论,一分钟后有一百个人访问该篇文章,那么也是可以减少非常多数据库的访问,所以改静态化页面的想法还是可行的至于linux,改天再去讨教几招)。

下面讲讲伪静态化(局部静态话就算了,到处ajax更新局部就OK了);首先说哈,伪静态化其实是动态化的网页,只是更改路由而已,为了SEO而非服务器数据库的负担。、

3、伪静态化

伪静态化在用ThinkPHP实现还是相当容易的,不过就是开启apache的rewrite模块,更改ThinkPHP里面的URL模式为pathinfo模式就好了

http://serverName/appName/module/action/year/2008/month/09/day/21

还可以设置常量(‘’URL_HTML_SUFFIX'=>'shtml‘)给上面的路由变成:

http://serverName/appName/module/action/year/2008/month/09/day/21.shtml

是不是更加静态化啦,当然这个是PHP代码上输出URL是这样,但是服务器可不认识:

1、如何代码上输出这样的URL:

2、让服务器正确解析路由:

在httpd.conf文件中,找到以下开启apache的重写模块:

#注释:去掉前边的" # "开启rewrite服务,重启服务器生效
#LoadModule rewrite_module modules/mod_rewrite.so

#注释:http-vhosts.conf文件是虚拟域名配置的文件,开启改文件可以配置虚拟域名,一般默认是开启的
#Include conf/extra/httpd-vhosts.conf 

ThinkPHP就是更改apache的.htacess文件给伪静态路由加上index.php:

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>
http://serverName/Blog/read/id/1 《=》http://serverName/index.php/Blog/read/id/1

改了配置文件后上面两个网址对于服务器是一样的,会解析到同一个虚拟主机文件夹。

参考文章:

http://www.cnblogs.com/caoruiy/p/4698938.html
百度百科-动态页面静态化
http://www.jb51.net/article/59619.htm
http://www.cnblogs.com/yizhu2000/archive/2008/09/01/1281532.html
原文地址:https://www.cnblogs.com/xuweiqiang/p/7212674.html