整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

ThinkPHP5中如何实现模板完全静态化

ThinkPHP5中如何实现模板完全静态化

模板完全静态化,也就是通过模板完全生成纯静态的网页,相比动态页面和伪静态页面更安全更利于SEO访问更快。相比前二者各有利弊吧,现在稍微对这三种形式的优缺点对比一下,以及在ThinkPHP5项目中实现完全静态化的基本过程。

对比

1. 动态与真静态

页面静态化与动态页的对比,静态没有了SQL和一些后端脚本运行,安全稳定,访问速度快,对SEO友好(网上也有说现在的搜索引擎已经对动态网页的抓取没什么压力了),但是搜索引擎再强大,静态的URL也比动态的后面带问号冒号什么的要好看,不对SEO友好对普通浏览用户者也是友好(好看第一)。但是生成静态页面的弊端,也就是如果一个博客网站,随着文章内容的增多,那生成的页面也不断增多,就算一个html就30几Kb,数量多的情况下也挺耗存储空间,网上也有说频繁生成静态页面化,容易让硬盘出现坏道。这个我的看法是不好测试可以忽略,因为现在多数是使用云服务器或云虚拟主机,那些都不是物理硬件,就算太过碎片导致硬盘损坏,网站也能正常访问的,因为那是云服务器。

2. 真静态与伪静态

这二者的对比看起来像是正统之争,因为大家都知道伪静态还是动态页,只是Apache通过URL重写规则让其变成了像静态网页的样子。主要也是让自己对SEO友好,但是相比真静态多了Apache的步骤,所以也就比较耗费一些服务器的资源。而真静态的缺点上面也说了,在项目中的选择看需求,各有利弊,北桥苏的使用主要是自己网站有时要优化一下速度所以就做了模板静态化,以下是操作过程。

实现思路

1. 根据模块控制器自动递归创建目录。

2. file_exists判断生成的静态页是否存在

3. 或判断过期与否,存在重定向到静态网页

4. file_put_contents($file,$content)函数生成页面。

编码

1. 目录的创建

/*
 * 递归创建目录
 * @param string $dir 文件目录路径
 * @return boolean 创建结果
 * **/
function mkdirs($dir)
{
 if(!is_dir($dir))
 {
 if(!mkdirs(dirname($dir))){
 return false;
 }
 if(!mkdir($dir,0777)){
 return false;
 }
 }
 return true;
}

2. 在基类中初始化需创建的目录

protected $staticHtmlDir=""; //静态模板生成目录
protected $staticHtmlFile=""; //静态文件
protected function _initialize() {
 parent::_initialize();
 $this->staticHtmlDir="html".DS.$this->request->controller().DS;
//……………………………………………………………………

3. 基类中的生成前与生成后的方法。

//判断是否存在静态
public function beforeBuild($param) {
 //生成静态
 //$baseDir="html".DS.$this->request->controller().DS;
 if(is_array($param)) {
 $param=implode("_",$param);
 }
 $this->staticHtmlFile=$this->staticHtmlDir.$this->request->action().($param?$param:'').'.html';
 if(mkdirs($this->staticHtmlDir)) {
 if(file_exists($this->staticHtmlFile) && filectime($this->staticHtmlFile)>=time()-60*60*24*5) { //静态文件存在
 $this->redirect('/'.$this->staticHtmlFile);
 }
 }
 }
//开始生成静态文件
public function afterBuild($html) {
 if(!empty($this->staticHtmlFile) && !empty($html)) {
 if(file_exists($this->staticHtmlFile)) {
 unlinnk($this->staticHtmlFile);
 }
 if(file_put_contents($this->staticHtmlFile,$html)) {
 $this->redirect('/'.$this->staticHtmlFile);
 }
 }
 }

4. 视图控制器中的使用。

ThinkPHP5中fetch方法返回给file_put_contents函数作为content就可以生成一个完整的静态页面了。

静态是指静态页面(.html),伪静态是指以静态页面(.html)结尾的文件缓存

两种静态对于SEO而言都是一样的。

真静态:



  • 可以有效减少服务器对数据响应的负荷
    • 不用调动数据库,响应速度快
    • 安全性高
    • 缺点:占用硬盘空间,每次需要手动生成

    伪静态:



    • 可以方便的实现对化化引擎的优化,并且比生成静态更加方便
    • 占空间比较小
    • 首页每天都自动变化,不用维护
    • 缺点:访问的响应速度不如真静态,需调用数据库

    伪静态大量使用,CPU负荷就会高,特别是访问量大的时候,当然缓存是可以弥补的。

    真静态不用调取数据库访问速度是很快的,也是可以减轻数据库的压力,需要的时候也是可以做优化的,当然SEO真伪静态也不是太重要了。

    thinkphp生成静态页面方法

    使用buildHtml


    1:在根目录下的全局index.php中加下面这行:

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

    2:在项目的配置文件config.php中加下面这行:

    'HTML_FILE_SUFFIX'=> '.html',// 默认静态文件后缀

    3:在需要生成静态页的action里加入下面显红的代码

    public function view(){
     $wheres="id=$_GET[id]";
     $news=$this->news->where($wheres)->find();
     $this->assign("news", $news);
     $this->buildHtml('1', HTML_PATH . '/news/', 'view', 'utf8');
     $this->display();
    }

    buildHtml方法

    参数1:生成的静态页名称

    参数2:静态页保存的目录

    参数3:生成静态页的方法名

    参数4:静态页编码(是utf8,不是utf-8)

    、为何要使用缓存技术?

    作用:对于一个日访问量达到百万级的门户网站,速度快慢很大程度上决定了网站的收入。除了优化网站内容显示策略外,提升网站速度最好的方法便是“静态缓存/动态缓存”技术。

    静态缓存:动态页面转换成静态页面,速度将提升2至10倍,如:文件缓存技术(传统手段);如果静态页面能够缓存到内存里,速度将提升2至3个数量级,如:memcache缓存技术(流行);

    动态缓存:即,局部缓存,进将不需要实时更新的数据缓存,并不是整个页面;

    二、缓存的方法主要要哪些?

    静态缓存:缓存的是整个页面;

    动态缓存:缓存的是页面的局部,即,局部缓存;

    局部不缓存:利用js、Ajax(异步)实现缓存页面的局部不缓存

    三、基于ThinkPHP的缓存实现

    (1)静态缓存、动态缓存、局部不缓存的含义/用途

    静态缓存:生成静态页面——缓存的是整个页面;

    动态缓存:仅对数据库中的数据进行了缓存,即“通过动态缓存,不需要再读取数据库了,直接通过缓存文件来调取相应数据”;

    局部不缓存:实现缓存页面中某一部分不缓存,如:登录/退出、点击量;

    (2)静态缓存的实现,在config.php文件中作如下配置:

    //开启静态缓存(默认保存在Html/文件夹中)

    'HTML_CACHE_ON'=>true,

    'HTML_CACHE_RULES'=> array(

    //'*'=>array('{$_SERVER.REQUEST_URI|md5}','30'), //根据当前的URL进行缓存

    /**

    * …更多操作的静态规则

    * '控制器名/方法名'=> array('缓存文件的名称','静态缓存有效期','附加规则'),

    * {:module}:控制器名

    * {:action}:方法名

    * {id}:get参数值

    */

    'Show:index'=>array('{:module}_{:action}_{id}',0),//0:永久有效

    ),

    (3)动态缓存的实现:两种方式(文件缓存、memecache缓存)

    1、文件缓存(默认方式)

    ThinkPHP的S()函数将“从数据库中获得的数据”缓存到“文件”中;

    缓存文件默认保存到“Runtime/Temp/”文件夹中;

    存数据格式:S('缓存名称','缓存数据','缓存时间');

    存数据:S('index_list',$list,10); // $list:从数据库中读取的数据

    读数据:S('index_list'); // 直接从缓存文件读取,不再经过数据库

    2、memecache缓存

    第一步:安装Memcached

    第二步:memecache缓存配置(在config.php文件中作如下配置:)

    //开启动态缓存(memecache缓存)

    'DATA_CACHE_TYPE'=>'Memcache',//缓存类型

    'MEMCACHE_HOST'=>'localhost',//本地服务器地址

    'MEMCACHE_PORT'=>11211,//默认端口

    'DATA_CACHE_TIME'=>3600,//全局缓存时间:特别注意这里不要加引号,否则将不起作用!!!

    第三步:通过S()函数实现“动态缓存”

    ThinkPHP的S()函数将“从数据库中获得的数据”缓存到“内存”中;

    存数据:S('index_list',$list,10);

    读数据:S('index_list')

    3、redis缓存

    第一步:安装redis及php-redis拓展

    详见另外两篇文章

    第二步:redis缓存配置

    //动态缓存配置:

    'DATA_CACHE_TIME'=>3600,

    //开启动态缓存(Redis缓存)

    'DATA_CACHE_TYPE'=>'Redis',

    'REDIS_HOST'=>'127.0.0.1',

    'REDIS_PORT'=>6379,//默认端口

    第三步:通过cache()函数实现“动态缓存”

    1 缓存初始化

    cache(array('type'=>'xcache','expire'=>60));

    2 缓存设置

    cache('a',$value);

    3 缓存读取

    $value=cache('a');

    4 缓存删除

    cache('a',null);

    拓展:使用查询缓存方式实现动态缓存

    对于及时性要求不高的数据查询,我们可以使用查询缓存功能来提高性能,而且无需自己使用缓存方法进行缓存和获取。

    新版内置的查询缓存功能支持所有的数据库,并且支持所有的缓存方式和有效期。

    在使用查询缓存的时候,只需要调用Model类的cache方法,例如:

    $Model->cache(true)->select();

    如果使用了cache(true) ,则在查询的同时会根据当前的查询SQL生成查询缓存,默认情况下缓存方式采用DATA_CACHE_TYPE 参数设置的缓存方式(系统默认值为File表示采用文件方式缓存),缓存有效期是DATA_CACHE_TIME 参数设置的时间,也可以单独制定查询缓存的缓存方式和有效期:

    $Model->cache(true,60,'xcache')->select();

    表示当前查询缓存的缓存方式为xcache,并且缓存有效期为60秒。

    同样的查询,如果没有使用cache方法,则不会获取或者生成任何缓存,即便是之前调用过Cache方法。

    查询缓存只是供内部调用,如果希望查询缓存开放给其他程序调用,可以指定查询缓存的Key,例如:

    $Model->cache('cache_name',60)->select();

    则可以在外部通过S方法直接获取查询缓存的内容,

    $value=S('cache_name');

    除了select方法之外,查询缓存还支持find和getField方法,以及他们的衍生方法(包括统计查询和动态查询方法)。具体应用的时候可以根据需要选择缓存方式和缓存有效期。

    (4)动态缓存应用实例

    public function index(){

    if(!$list=S('index_list')){

    //echo 111;//测试是否进行了动态缓存

    $list=M('cate')->where(array('pid'=>0))->order('sort')->select();

    S('index_list',$list,10);

    }

    $this->cate=$list;

    $this->display();

    }

    (5)局部不缓存的实现:两种方式(JavaScript、异步)

    1、JavaScript

    前台模板:

    <span>点击量<script src="{:U('Show/hitsCount',array('id'=>$blog['id']))}"></script>次</span>

    后台控制器:

    public function hitsCount(){

    $id=I('id');

    //点击次数:每次打开博文后点击次数+1

    //(当然也可以设置一个IP地址只能增加一次:记录用户的IP就显得很重要了)

    $where=array('id'=>$id);

    $hits=M('blog')->where($where)->getField('hits');

    M('blog')->where($where)->setInc('hits');//如果增2:setInc('hits',2)

    echo 'document.write('.$hits.')';//这一步很关键:获得的数据赋值给前台静态缓存页面

    }

    2、异步

    详见本教程中的文章:异步操作(Ajax请求)