Moke|墨客

 找回密码
 立即注册
搜索
查看: 6640|回复: 0

WordPress博客如何建立Widget缓存

[复制链接]

3636

主题

0

回帖

3681

积分

超级版主

Rank: 8Rank: 8

积分
3681
发表于 2016-5-12 18:17:49 | 显示全部楼层 |阅读模式






                  WordPress 的 Widget 功能凭借其容易定制和排版灵活的特点,我在做项目的时候特别喜欢用。最近在给雷锋网改版的时候除了首页的分类推荐使用 Widget 来排版以外,iOS 榜单也做成了 Widget,由于榜单是通过 iTunes 接口来获取数据的,因此数据必须缓存一段时间,才能避免每次访问都需要从接口获取数据的问题。嗯,今天就说说怎么给 Widget 设置缓存。
  先简单讲解一下 WordPress 默认的两种缓存机制,一种是 Transient Cache,Transient Cache通过数据库的 options 表进行缓存,会产生两行记录,一行用于记录缓存内容,一行用于记录缓存时间,在调用的时候,至少产生两次数据库查询(没有任何数据库缓存的情况下);另一种是 Object Cache,在没有安装任何缓存插件的情况下,WP_Object_Cache 会把数据缓存到 GLOBAL 变量的一个元素里,缓存内容只对当前页面有效,正是因为这一特点,在这个项目里应该选择 Transient Cache 来缓存 Widget 的数据。
  接下来先写一个最简单的 Widget:
add_action('widgets_init', array('Test_Widget', 'register')); class Test_Widget extends WP_Widget {     // 注册 Widget     function register() {         register_widget('Test_Widget');     }      // 构造函数     function __construct() {         $widget_ops = array('classname' => 'test_widget', 'description' => __( '测试挂件') );         parent::__construct('test_widget', __('Test Widget'), $widget_ops);     }     // Widget 主体输出     function widget( $args, $instance ) {         extract( $args );         //......     }       // 保存 Widget 参数     function update( $new_instance, $old_instance ) {         $instance = $old_instance;         //......         return $instance;     }     // Widget 设置面板     function form( $instance ) {         //......     } }  要给 Widget 建立缓存的话,我必须得同时实现这些要求:缓存定期自动更新,更新 Widget 参数的时候清除已有缓存,删除 Widget 的时候把相关的缓存也删除掉。前两点我们可以通过修改 Test_Widget::update() 和 Test_Widget::widget() 实现,修改后的 class Test_Widget 为:
class Test_Widget extends WP_Widget {     // 注册 Widget     function register() {         register_widget('Test_Widget');     }     // 构造函数     function __construct() {         $widget_ops = array('classname' => 'test_widget', 'description' => __( '测试挂件') );         parent::__construct('test_widget', __('Test Widget'), $widget_ops);     }     // Widget 主体输出     function widget( $args, $instance ) {         extract( $args );         // 如果缓存已经过期,则重新生成结果         if(false === get_transient($args['widget_id'])) {             /*             ......             执行 Widget 主体,在输出的同时把结果保存到 $data 变量里             ......             */            // 运行结果缓存 1 小时             set_transient($args['widget_id'], $data, 3600);         } else {             echo get_transient($args['widget_id']);         }         //......     }     // 保存 Widget 参数     function update( $new_instance, $old_instance ) {         $instance = $old_instance;         // 更新参数时删除已有的缓存         delete_transient($this->id);         //......         return $instance;     }     // Widget 设置面板     function form( $instance ) {         //......     } }  最后要在删除 Widget 的时候把缓存删除,目前我使用的是一个比较暴力的方法:
add_action('sidebar_admin_setup', 'delete_test_widget_cache')); function delete_test_widget_cache() {     if(isset($_POST['delete_widget']) && $_POST['delete_widget'] && isset($_POST['widget-id']) && $_POST['widget-id']) {         delete_transient($_POST['widget-id']);     } }  至此,Widget 缓存机制几经完成,但在删除插件时删除已有缓存这一步里,使用了一个暴力的方法,该方法缺点是:你删除其他的 Widget 也会尝试删除缓存。经过分析 WordPress 源代码,发现删除 Widget 里会调用 Widget Class 里的 update_callback() 方法,利用这个方法去删除 Widget 的缓存,是一个比较文艺的做法。我重新改写后的 Class 如下:
class Test_Widget extends WP_Widget {     // 注册 Widget     function register() {         register_widget('Test_Widget');     }     // 构造函数     function __construct() {         $widget_ops = array('classname' => 'test_widget', 'description' => __( '测试挂件') );         parent::__construct('test_widget', __('Test Widget'), $widget_ops);     }     // Widget 主体输出     function widget( $args, $instance ) {         extract( $args );         // 如果缓存已经过期,则重新生成结果         if(false === get_transient($args['widget_id'])) {             /*             ......             执行 Widget 主体,在输出的同时把结果保存到 $data 变量里             ......             */            // 运行结果缓存 1 小时             set_transient($args['widget_id'], $data, 3600);         } else {             echo get_transient($args['widget_id']);         }         //......     }     // 保存 Widget 参数     function update( $new_instance, $old_instance ) {         $instance = $old_instance;         // 更新参数时删除已有的缓存         delete_transient($this->id);         //......         return $instance;     }     // Widget 设置面板     function form( $instance ) {         //......     }     // 下面这个函数是新增加的,用来删除缓存     function update_callback($widget_args = 1) {         // 删除缓存         delete_transient($this->id);         delete_transient($this->id);         // 调用原来的 update_callback() 方法,防止出错         parent::update_callback($widget_args);     } }PS一句:PHP Class 真的很好用,能减少大量代码,以后要多多学习。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

 

 

快速回复 返回顶部 返回列表