作者:西瓜玩偶

上一篇文章介绍了如何设计数据库,从而达到可拓展性的目的。下面的篇幅将介绍在PHP的代码方面,如何设计才能达到可拓展性。

2. 钩子(hook)方法

在给一个系统书写插件的时候,我们往往需要在原来工程的某个特定位置加入一段代码。如果原来的工程没有任何特殊的设计,那么我们的做法肯定是找出原来工程的相关代码,然后在里面插入我们想要实现的功能,但是这样就毫无扩展性可言了。例如,原工程如果有升级,那么我们拿到了原工程的代码之后,又要找到原来的地方,又要重新插入一遍自己想要实现的功能,费时费力。

在WordPress中,为了避免这样的问题,引入了一个钩子方法的概念。所谓“钩子”,其实可以理解为代码的插入点。这也就是说,如果原工程在设计时加入了钩子方法的调用,我们便可以在调用钩子方法的地方插入代码。WordPress在设计的时候考虑得相当周到,可以说插件开发者需要插入代码的地方,都已经有了钩子方法了。

钩子方法的本质其实就是是动态调用函数。每一个钩子方法都有特定的名称以及定义,例如 save_post ,表示当一篇文章被保存时需要执行的代码,WordPress在调用这个方法时,会给我们传入被保存的文章ID。

如果我需要在文章被保存的时候执行一些特殊功能,比如说给某个指定的邮箱发邮件。那么我首先需要在插件中实现发邮件的功能,并且在特定的钩子方法中注册我的函数。例如:

function sent_email_to_myself($post_id) {
  // 这里略过实现发送Email的功能……
}

add_action('save_post', 'send_email_to_myself', 10, 1);

add_action 是由WordPress定义的函数。其中前两个参数,第一个为指定需要插入代码的位置,第二个为指定要插入那个函数。最后的两个参数一个表明执行的优先级,一个表明接受的参数数量,与下文内容并无太大关系,故此处略过。

当我们打开一个WordPress页面时,WordPress会遍历插件列表,执行每一个插件的入口PHP文件。这样上述代码就会被执行,我们的插件就利用 add_action 函数的调用,把发送邮件的功能注册在了 save_post 这个钩子方法上。到了保存文章的时候,WordPress会调用 save_post 这个钩子方法——它首先查找钩子方法的注册列表,找出有哪些函数注册在了 save_post 上,然后根据优先级顺序依次调用执行。这样就达到了在特定的位置执行插件定义的代码的目的。

这样做的好处是,无论WordPress如何升级,只要钩子方法的定义没有改变,那么原有插件就可以不加修改正常工作。这样就相当于降低了原工程与插件的耦合度。

然而有利必有弊,这样做的代码执行速度肯定是没有直接调用函数来得快。不过对于WordPress这样的强调高可扩展性的工程,使用这样的技巧显然是利大于弊的。我们亦可以在我们的工程中借鉴这样的思路,从而使我们的工程也具有高可扩展性。

(完)

参考资料:

https://developer.wordpress.org/reference/functions/add_action/

https://codex.wordpress.org/Plugin_API/Action_Reference/save_post

WordPress的可拓展性初探(二)_WordPress的可拓展性初探