看phpwind的官方网站,发现有个很重要版块为“phpwind 插件开发”,第一感觉是phpwind有个很完善的插件体系,吸引开发者来基于插件体系进行二次开发。于是乎我饶有兴趣地解析一下phpwind的插件体系的实现。我先说说在我看来插件体现比较重要的两个特征:
对于第一个特征phpwind体现得还不错,在后台有个专门的栏目是管理插件,能够对放在hack目录下的插件进行安装和卸载,而插件本身的属性(info.xml)、管理界面(admin.php)、功能界面(index.php)就需要在插件子目录下进行专门的开发,只需要按照规定的文件名进行命名就行,一个典型的插件目录结构如下图所示:
其实phpwind的插件管理功能实现很简单,也就是分析hack目录下所有子文件夹的目录结构,解析出所有插件,界面上显示的插件名称来自于各个插件目录下的info.xml,而对每个插件的管理配置都是各个插件目录下admin.php,插件的各个属性有个类似于key-value的名字为hack的表来存储。
但对于第二个特征,phpwind就做得很粗,对于用户自定义的插件,phpwind只提供整个插件通过url的访问,而不能把插件插到既有的功能流程中去。官方提供的插件“评价”可以插入到发帖等既有流程中,但实现的方式确是在“read.php”源代码里硬生生的加入了对评价的支持,如:
//评价功能开启 $rateSets = unserialize($db_ratepower); if(!$forumset['rate'] && $rateSets[1] && isset($db_hackdb['rate'])){ list($noAjax,$objectid,$typeid,$elementid) = array(TRUE,$tid,1,'vote_box'); require_once R_P . 'hack/rate/index.php'; }
因此想通过插件的方式来改造既有功能就无门了。对于自制的插件,phpwind只能通过root_url/hack.php?H_name=plugin_name,看hack.php的源码,发现实现非常简单,仅仅就是通过plugin_name把插件目录下的index.php require进来,源码如下:
define('SCR','hack'); if(isset($_GET['action']) && $_GET['action'] == 'ajax'){ define('AJAX','1'); } require_once('global.php'); InitGP(array('H_name')); if (preg_match('/^http/i',$H_name)) { Showmsg($H_name); } elseif(!$db_hackdb[$H_name] || !is_dir(R_P.'hack/'.$H_name) || !file_exists(R_P."hack/$H_name/index.php")){ Showmsg('hack_error'); } define('H_P',R_P."hack/$H_name/"); $basename = "hack.php?H_name=$H_name"; $hkimg = "hack/$H_name/image"; $forumtitle = strip_tags($db_hackdb[$H_name][0]).' '; if (!defined('AJAX')) { require_once(R_P.'require/header.php'); } require_once(H_P.'index.php');
因此,只能说phpwind的插件体系是个很简陋的玩意,只是简单的帮你管理一下你自己的代码,让它从目录结构上表现得规矩一点,如果真的希望通过用户开发插件来加强或定制已存在的功能,就需要深入到各个主要功能流程中,在流程的各个环节加入插入点,让用户的自定义插件能真正深入其中。