WordPress 的 Hook 机制在 Discuz 二次开发中的应用

最近工作需要对 Discuz 做二次开发,本着最小化改动方便以后升级的原则,我引入了 WordPress 的 Hook 机制(即 Plugin API)来降低二次开发代码与 Discuz 原生代码的耦合度。

WordPress 内部提供了许多 Hook(钩子),以便插件可以将相应的 action 或 filter 挂接上去接管或改进 WordPress 的默认处理来达到自己期望的目的,在处理完毕后将控制权重新交给 WordPress。而我们所要做的就是将这种机制移植到 Discuz 中,所幸的是,WordPress 的 Hook 机制并没有过多地依赖于它的其它核心程序,所以基本不需要做多少修改就可以拿来使用。

基本步骤

  1. 在 Discuz 安装目录新建一个文件夹,命名为extra,复制 WordPress 的wp-includes/plugin.php文件到此文件夹。为了符合 Discuz 名命名规范,将文件重命名为plugin.func.php
  2. 为了避免潜在的函数命名冲突,可以将plugin.func.php文件里的函数名称都加上前缀,例如do_action()修改成dz_do_action();另外 plugin_basename(), register_activation_hook(), register_deactivation_hook(), register_uninstall_hook() 等函数可以删除。
  3. extra文件夹新建一个php文件,命名为hooks.inc.php,这里放置绝大部分 filter 和 action,将它们放在该文件中的一个最大的好处是方便集中维护。
  4. 载入相关文件。打开include/common.inc.php文件,找到
     
    require_once DISCUZ_ROOT.'./config.inc.php';
    

    在该行代码下面添加

     
    require_once DISCUZ_ROOT.'./extra/plugin.func.php';
    require_once DISCUZ_ROOT.'./extra/hooks.inc.php';
    

    至此,基本的 Hook 机制已经建立

实际应用示例

接下来我们就可以开始添加自己的代码了。举个例子,Discuz 中$discuz_auth_key是这样定义的:

$discuz_auth_key = md5($_DCACHE['settings']['authkey'].$_SERVER['HTTP_USER_AGENT']);

如果想将$discuz_auth_key的定义修改为md5(authkey+user_agent+ip)这样的形式,我们可以通过 filter 来实现。在$discuz_auth_key的定义代码下一行添加:

// 生成一个名为 discuz_auth_key 的钩子
$discuz_auth_key = dz_apply_filters('discuz_auth_key', $discuz_auth_key, $_DCACHE['settings']['authkey'], $_SERVER['HTTP_USER_AGENT'], $onlineip);

然后打开hooks.inc.php文件,添加以下代码

// 为了方便维护,所有 filter 类 hook 都以 filter_ 为前缀
function filter_discuz_auth_key($discuz_auth_key, $authkey, $ua, $ip) {
  // 符合自己设定的条件时才重新定义 authkey
  // 否则返回 Discuz 定义的 discuz_auth_key 原值
  if ($authkey && $ua && $ip) {
    $discuz_auth_key = md5($authkey . $ua . $ip);
  }
  return $discuz_auth_key;
}

// 将 filter 函数 filter_discuz_auth_key 挂接到 discuz_auth_key 钩子上
// 第三个参数的值 10 代表执行优先级,因为一个钩子上可以挂接多个callback函数
// 第四个参数的值 4 代表允许 filter_discuz_auth_key 函数接收的参数个数
add_filter('discuz_auth_key', 'filter_discuz_auth_key', 10, 4);

这样便达到我们所要的效果了。当然有些情况下还是无法避免了二次开发代码与原代码的夹杂在一起,不过由于有了 Hook 机制,这种情形已经可以大大减少了。

相关阅读
WordPress Plugin API

WordPress 的 Hook 机制在 Discuz 二次开发中的应用》上有4条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注