zoukankan      html  css  js  c++  java
  • ThinkPHP 3.2.3 数据缓存与静态缓存

    ThinkPHP 3.2.3 中手册中数据缓存的地址是:http://www.kancloud.cn/manual/thinkphp/1835

    静态缓存的地址是:http://www.kancloud.cn/manual/thinkphp/1839

    数据缓存

    使用 S 方法进行数据缓存,缓存文件默认的方式是文件缓存(DATA_CACHE_TYPE = File),文件缓存默认的保存路径是 ./Application/Runtime/Temp

    当使用默认的缓存方式时,不需要在配置文件中进行配置,直接在控制器中需要缓存数据的地方调用 S 方法即可:

    S(缓存名,缓存值,缓存时间)

    例如在 IndexController.class.php(./Application/Home/Controller/IndexController.class.php)要对首页数据进行缓存:

    <?php
    namespace HomeController;
    use ThinkController;
    use AdminCommonCategory;

    class IndexController extends Controller { //首页 public function index(){ if(!$top_cate = S('index_list')) { //读取顶级栏目 $top_cate = M('cate')->where(array('pid'=>0))->order('sort')->select(); $cate = M('cate')->order('sort')->select(); $bObj = M('blog'); $field = array('id','title','time'); foreach($top_cate as $key=>$val) { $cids = Category::get_children_id($cate,$val['id']); $cids[] = $val['id']; $where = array('cid'=>array('IN',$cids)); $top_cate[$key]['blog'] = $bObj->field($field)->where($where)->order('time DESC')->select(); } //缓存 S('index_list',$top_cate,3600*24);//1天,默认存储路径是 ./Application/Home/Runtime/Temp } $this->assign('top_cate',$top_cate); $this->display(); } }

    此时 ./Application/Runtime/Temp 中生成了 823c3bcf17c6b7276fa8799355c4c7c8.php

    <?php
    //000000086400a:7:{i:0;a:5:{s:2:"id";s:1:"1";s:4:"name";s:4:"HTML";s:3:"pid";s:1:"0";s:4:"sort";s:1:"1";s:4:"blog";a:0:{}}i:1;a:5:{s:2:"id";s:1:"3";s:4:"name";s:10:"JavaScript";s:3:"pid";s:1:"0";s:4:"sort";s:1:"3";s:4:"blog";a:1:{i:0;a:3:{s:2:"id";s:1:"1";s:5:"title";s:2:"js";s:4:"time";s:10:"1455438771";}}}i:2;a:5:{s:2:"id";s:1:"4";s:4:"name";s:3:"PHP";s:3:"pid";s:1:"0";s:4:"sort";s:1:"4";s:4:"blog";a:3:{i:0;a:3:{s:2:"id";s:1:"4";s:5:"title";s:20:"thinkphp关联模型";s:4:"time";s:10:"1456541875";}i:1;a:3:{s:2:"id";s:1:"3";s:5:"title";s:15:"无限极分类";s:4:"time";s:10:"1456541682";}i:2;a:3:{s:2:"id";s:1:"2";s:5:"title";s:6:"对象";s:4:"time";s:10:"1455438885";}}}i:3;a:5:{s:2:"id";s:1:"2";s:4:"name";s:7:"DIV+CSS";s:3:"pid";s:1:"0";s:4:"sort";s:1:"5";s:4:"blog";a:0:{}}i:4;a:5:{s:2:"id";s:1:"5";s:4:"name";s:5:"MySQL";s:3:"pid";s:1:"0";s:4:"sort";s:1:"5";s:4:"blog";a:0:{}}i:5;a:5:{s:2:"id";s:1:"6";s:4:"name";s:5:"Linux";s:3:"pid";s:1:"0";s:4:"sort";s:1:"6";s:4:"blog";a:0:{}}i:6;a:5:{s:2:"id";s:1:"8";s:4:"name";s:6:"其他";s:3:"pid";s:1:"0";s:4:"sort";s:1:"7";s:4:"blog";a:0:{}}}
    ?>
    View Code

    如果要改变缓存方式,例如不再把缓存存入文件,而是存入 Memcached 中,该项目中 PHP 的 Memcached 扩展是 Memcached:

    此时可以通过修改配置文件 ./Applicaiton/Home/Common/Conf/conf.php,添加:

        'DATA_CACHE_TYPE'=>'Memcached',
        'PERSISTENTID' => 'mlm_cache',//持久链接标示
        'MEMCACHED_HOST' => '127.0.0.1', //可数组形式
        'MEMCACHED_PORT' => '11211',//可数组形式
        'MEMECACHED_WEIGHT' => 0,//权重

    注:Memcached 的驱动可以在 http://www.thinkphp.cn/extend/559.html 进行下载并放到 ./ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php:

    <?php
    
    namespace ThinkCacheDriver;
    
    use ThinkCache;
    
    defined('THINK_PATH') or exit();
    
    /**
     * Memcache缓存驱动
     */
    Class Memcached extends Cache {
    
        public function __construct($options = array()) {
            if (!extension_loaded('memcached')) {
                throw_exception(L('_NOT_SUPPERT_') . ':memcached');
            }
            $servers = array();
            $persistent_id = C('PERSISTENTID') ? C('PERSISTENTID') : null;
    
            $this->options = $options;
            $this->options['expire'] = isset($options['expire']) ? $options['expire'] : C('DATA_CACHE_TIME');
            $this->options['prefix'] = isset($options['prefix']) ? $options['prefix'] : C('DATA_CACHE_PREFIX');
            $host = C('MEMCACHED_HOST') ? C('MEMCACHED_HOST') : '127.0.0.1';
            $port = C('MEMCACHED_PORT') ? C('MEMCACHED_PORT') : 11211;
            $weight = C('MEMECACHED_WEIGHT') ? C('MEMECACHED_WEIGHT') : 1;
            $weight_is_arr = is_array($weight);
    
    
            if (is_array($host)) {
                if (!is_array($port)) {
                    throw_exception('Memcached服务器IP和端口号要一一对应');
                }
                if ($weight_is_arr && count($weight) != count($host)) {
                    throw_exception('Memcached服务器IP和权重值要一一对应');
                }
                foreach ($host as $key => $value) {
                    $servers[] = array($value, $port[$key], $weight_is_arr ? $weight[$key] : $weight);
                }
            } else {
                if (is_array($port)) {
                    foreach ($port as $key => $value) {
                        $servers[] = array($host, $value, $weight_is_arr ? $weight[$key] : $weight);
                    }
                } else {
                    $servers[] = array($host, $port, $weight_is_arr ? $weight[0] : $weight);
                }
            }
            $this->handler = new Memcached($persistent_id);
            $this->handler->addServers($servers);
    //        $serverList = $this->handler->getServerList();
    //        var_dump($serverList);
    //        var_dump($this->handler->getStats());
    //        var_dump($this->handler->getOption());
    //        var_dump($this->handler->getVersion());
    // p($serverList);
        }
    
        /**
         * 读取缓存
         * @access public
         * @param string $name 缓存变量名
         * @return mixed
         */
        public function get($name) {
            N('cache_read', 1);
            return $this->handler->get($this->options['prefix'] . $name);
        }
    
        /**
         * 读取多个元素值
         * @param  array  $keys [要读取的元素key数组]
         * @return [boolean]       [返回值]
         */
        public function getMulti($keys = array()) {
            if (empty($keys))
                return '';
            N('cache_read', 1);
            return $this->handler->getMulti($keys);
        }
    
        /**
         * 写入缓存
         * @access public
         * @param string $name 缓存变量名
         * @param mixed $value  存储数据
         * @param integer $expire  有效时间(秒)
         * @return boolen
         */
        public function set($name, $value, $expire = 0) {
            N('cache_write', 1);
            if (is_null($expire)) {
                $expire = $this->options['expire'];
            }
            $name = $this->options['prefix'] . $name;
            if ($this->handler->set($name, $value, $expire)) {
                return true;
            }
            return false;
        }
    
        /**
         * 写入多个元素
         * @param [array] $items  [要写入的健/值元素数组]
         * @param [int] $expire [有效时间(秒)]
         */
        public function setMulti($items, $expire = 0) {
            N('cache_write', 1);
            if (is_null($expire)) {
                $expire = $this->options['expire'];
            }
            $name = $this->options['prefix'] . $name;
    
            if ($this->handler->setMulti($items, $expire)) {
                return true;
            }
            return false;
        }
    
        /**
         * 添加一个元素,如果这个元素已经存在,则失败
         * @param [string]  $key    [要添加元素的key]
         * @param [string]  $value  [要添加元素的值]
         * @param integer $expire [有效时间]
         * @return boolean
         */
        public function add($key, $value, $expire = 0) {
            N('cache_write', 1);
            return $this->handler->add($key, $value, $expire);
        }
    
        /**
         * 替换已存在key下的元素,如果不存在此key则失败
         * @param  [string]  $key    [要替换的key]
         * @param  [string]  $value  [要替换的值]
         * @param  integer $expire [有效时间]
         * @return [boolean]          
         */
        public function replace($key, $value, $expire = 0) {
            N('cache_write', 1);
            return $this->handler->replace($key, $value, $expire);
        }
    
        /**
         * 删除缓存
         * @access public
         * @param string $name 缓存变量名
         * @return boolen
         */
        public function rm($name) {
            $name = $this->options['prefix'] . $name;
            return $this->handler->delete($name);
        }
    
        /**
         * 清除缓存
         * @access public
         * @return boolen
         */
        public function clear() {
            return $this->handler->flush();
        }
    
    }
    Memcached.class.php

    同时 ./Application/Home/Controller/IndexController.class.php 修改为:

    <?php
    namespace HomeController;
    use ThinkController;
    use AdminCommonCategory;
    use ThinkCacheDriverMemcached;
    
    class IndexController extends Controller {
        //首页
        public function index(){
            
            if(!$top_cate = S('index_list')) {
    
                //读取顶级栏目
                $top_cate = M('cate')->where(array('pid'=>0))->order('sort')->select();
                $cate = M('cate')->order('sort')->select();
                $bObj = M('blog');
                $field = array('id','title','time');
                
                foreach($top_cate as $key=>$val) {
                    $cids = Category::get_children_id($cate,$val['id']);
                    $cids[] = $val['id'];
                    $where = array('cid'=>array('IN',$cids));
                    $top_cate[$key]['blog'] = $bObj->field($field)->where($where)->order('time DESC')->select();
                }
    
                //缓存
                S('index_list',$top_cate,3600*24);//1天,默认存储路径是 ./Application/Home/Runtime/Temp 
            }
            
            $this->assign('top_cate',$top_cate);
            $this->display();
        }
    }

    在服务器端开启 Memcached,刷新首页,此时 Runtime/Tmp 下不会再生成缓存文件;

    通过 Telnet 客户端查看 Memcached 服务器中存储的缓存:

    stats items
    STAT items:12:number 1
    STAT items:12:age 216
    STAT items:12:evicted 0
    STAT items:12:evicted_nonzero 0
    STAT items:12:evicted_time 0
    STAT items:12:outofmemory 0
    STAT items:12:tailrepairs 0
    STAT items:12:reclaimed 0
    STAT items:12:expired_unfetched 0
    STAT items:12:evicted_unfetched 0
    STAT items:12:crawler_reclaimed 0
    STAT items:12:crawler_items_checked 0
    STAT items:12:lrutail_reflocked 0
    END
    stats cachedump 12 0
    ITEM index_list [898 b; 1456615330 s]
    END
    

    (Memcache 查看列出所有key方法:http://www.ttlsa.com/memcache/memcache-list-all-keys/)  

    首页在 Memcached 中的缓存为 index_list。

    静态缓存

    静态缓存就类似于一些 CMS 中直接把页面静态化,在静态文件的生存周期内直接访问静态的 HTML 文件

    Home 模块的静态缓存需要在配置文件 ./Application/Home/Common/Conf/config.php 中添加配置:

        //开启静态缓存
        'HTML_CACHE_ON'=>true,
        'HTML_CACHE_RULES'=>array(
            
            //给Show控制器的index方法生成缓存,默认的保存位置是 ./Application/Html
            'show:index'=>array('{:module}_{:action}_{id}',10) //参数:缓存文件的名称,缓存生存周期(0代表永不过期)
        ),

    以上配置表示缓存 show 控制器的 index 方法,保存的文件名是 show_index_{id},id 表示 $_GET['id'],也就是说(show 控制器的 index 方法用于查看文章内容页,通过 URL 传递的参数 id 来访问相应 id 的文章)访问 id 为 4 的文章时会生成 show_index_4.html 文件,默认保存在 ./Applicaiton/Html 中

    控制器 ./Application/Home/Controller/ShowController.class.php:

    <?php
    namespace HomeController;
    use ThinkController;
    use AdminCommonCategory;
    
    class ShowController extends Controller{
        //展示页
        public function index() {
            
            $id = (int)$_GET['id'];
            $where = array('id'=>$id,'del'=>0);
            $field = array('id','title','content','time','cid');
            $blog = M('blog')->field($field)->where($where)->find();
            
            //实体转换成字符
            $blog['content'] = htmlspecialchars_decode(html_entity_decode($blog['content']));
            $this->blog = $blog;
            
            //面包屑,通过子分类查询所有父分类信息
            $cate = M('cate')->order('sort')->select();
            $this->parent = Category::get_parents($cate, $blog['cid']);
             
            $this->display();
        }
        
        
        //点击次数不缓存
        public function inc_click() {
            $id = (int)$_GET['id'];
            $where = array('id'=>$id);
            //click自增1
            M('blog')->where($where)->setInc('click');//默认自增1 
            $click = M('blog')->where($where)->getField('click');
            echo 'document.write('.$click.')';
        }
    }

    如果在该页面中有不需要缓存的内容,例如文章的点击次数,每进行一次访问,次数加 1,可以通过 js 的形式来访问相应的点击方法,例如视图文件 ./Application/Home/View/Show/index.html:

    <include file='Common:header'/>    
        <link rel="stylesheet" href="__PUBLIC__/Css/show.css" />
        <!--引入ueditor代码高亮插件-->
        <link rel="stylesheet" href="__ROOT__/Data/ueditor/third-party/SyntaxHighlighter/shCoreDefault.css">
        <script src="__ROOT__/Data/ueditor/third-party/SyntaxHighlighter/shCore.js"></script>
        <!--引入插件结束-->
        <!--使用ueditor代码高亮插件-->
        <script>
            SyntaxHighlighter.all();
        </script>
        <!--使用ueditor代码高亮插件结束-->
    </head>
    <body>
    <!--头部-->
    <include file='Common:nav'/>
    <!--主体-->
        <div class='main'>
            <div class='main-left'>
                <div class='location'>
                    <a href="">首页</a>>
                    <?php $last = count($parent) - 1;?>
                    <foreach name="parent" item="v">
                        <a href="{:U('/c_'.$v['id'])}">{$v.name}</a>
                        <if condition="$last neq $key">></if>
                    </foreach>
                </div>
                <div class="title">
                    <p>{$blog.title}</p>
                    <div>
                        <span class='fl'>发布于:{$blog.time|date="Y年m月d日",###}</span>
                        <span class='fr'>已被阅读<script src="{:U('Home/Show/inc_click',array('id'=>$blog['id']),'')}"></script></span>
                    </div>
                </div>
                <div class='content' style="word-break: break-all;">
                    {$blog.content}
                </div>
            </div>
        <!--主体右侧-->
        <include file='Common:right'/>
        </div>
    <!--底部-->
        <include file='Common:bottom'/>
  • 相关阅读:
    页面使用本地IE版本
    C#获取客户端ip
    获取存储过程返回数据
    自制js表格排序
    读取数据用rs.open sql,conn,1,1
    学习存储过程
    COLLATE Chinese_PRC_CI_AS
    sqlserver存储过程语句(转)
    用P3P header解决iframe跨域访问cookie(转载)
    java通过dom创建和解析xml
  • 原文地址:https://www.cnblogs.com/dee0912/p/5223923.html
Copyright © 2011-2022 走看看