phpwind 9插件开发速成教程(含实例和源码)

2013-01-15 14:31:46来源:phpwind作者:

这篇文章被收录与phpwind开发文档之中,教主同学写的一篇phpwind9插件开发速成心法。
 

这篇文章被收录与phpwind开发文档之中,教主同学写的一篇phpwind9插件开发速成心法。
 

什么是插件

插件是增加网站功能,实现差异化运营的重要手段
通常所说的插件,其实都是泛指插件与扩展,两者区别是:

  1. 插件 具有独立访问地址,功能可以自成体系的功能模块
  2. 扩展 通过钩子系统注入到系统中以达到接管或改进原有系统的功能模块

有一个比较容易混淆的概念是,phpwind9.0的导航上有一个应用中心 这里所谓的应用,其实都是插件(插件也叫应用)

插件的原理

  1. 插件 是通过框架分发器的模式匹配功能来实现的,所以开发一个插件本质上跟开发应用是一样的
  2. 扩展 通过钩子系统注入到系统中的功能模块,依赖系统的功能运行而运行

准备工作

注册成为开发者

  1. 成为开发者,可以使你开发的插件为所有phpwind站点使用
  2. 可以让你的插件成为唯一,以防与其他开发者命名冲突
  3. 当然如果你愿意,这可以为你带来一笔收入
  4. 开发者注册地址

Zhanghao.JPG 身份认证.jpg

了解开发助手

  • 进入后台->站点设置->全局参数-> DEBUG 模式运行站点,输入520(或1314),开启开发者模式
  • 进入后台->云平台->应用管理->开发助手 按照提示输入,建立一个插件

App zhushou.jpg

  • 在src/extensions/目录下,能找到你刚生成的插件文件夹
  • 如果DEBUG模式为1314,还可以在前台页面上看到已埋的钩子标识

App gouzi.jpg

开发者版本

  1. 为了更好地与开发者保持交流,我们实时公布研发版本的代码动态,此上面的更新将全部放入下个版本
  2. 下载地址 https://github.com/phpwind/nextwind

插件开发规范

由于系统可能同时存在多个插件,尤其是云平台开通之后,插件安装极其便利,为了避免插件之间的冲突,定义如下规范:

插件唯一标识符

  1. 标识符由字符、数字组成,不能包含_
  2. 标识符需能明确表达插件的含义,否则无法通过云平台验证(不提交到云平台的插件略过)
  3. 标识符可以到云平台申请
  4. 比如当前申请到的唯一标识符为sign,以下皆以此为例

数据库命名规范

  1. 表命名 统一添加表前缀,表前缀为pw_app_sign_(pw_前缀是站长安装时选择的,可能各个站不一样)
  2. 扩展字段 插件不建议在原生数据表上增加字段,但并不限制。所有增加的字段必须带上前缀app_sign_

类命名(文件名)规范

  1. 所有类命名(Controller除外)必须带上前缀 App_Sign_,驼峰形式+下划线_

插件配置规范

为防止插件之间配置项命名冲突,我们作如下约定:
  1. 独立配置域 配置域命名规则为 app_sign
  2. 公共配置域 对于某些配置到公共配置域的配置项,配置项加前缀 app.sign.

钩子键名(alias)命名规范

  1. alias命名加前缀 app_sign

后台菜单项键名命名规范

  1. 键名命名加前缀 app_sign

用户组权限键名命名规范

  1. 键名命名加前缀 app_sign

开发演示

选取一个题材

我们选取互联网上SNS社区比较流行的一款增加用户粘性的互动游戏“动他一下”作为本次的开发示例。
别忘了,上开发者平台验证一下,是否已经有人开发过了哦

这个插件做些什么

  1. 应该有一个独立页面,列出我的所有好友,我可以轻松的动“他们”一下
  2. 访问别人空间的时候,我可以动“他们”一下
  3. 看别人帖子的时候,我也要动“他们”一下;
  4. 哦,别忘了,还需要一个后台设置

Dongta.jpg

创建应用

  • 进入后台->云平台->应用管理->开发助手
  • 按照提示,填写相关信息
  • 这里有三个选择需要注意一下
  1. 选择应用额外安装服务 这个有三个菜单可以选择,我们只需要在主导航中添加应用,故勾选nav_main
  2. 是否需要管理后台界面 选需要,会帮我们自动生成一个菜单项和演示页面
  3. 是否生成数据服务类 本应用要用到数据库,所以选需要
  • 提交,马上创建
  • 在应用管理,已安装菜单下,就能发现刚才创建的“动他一下”应用了
  • 嗯,logo不对,找到 src/applications/extensions/dongta/res/images 替换一张logo.jpg
  • 刷新,搞定!

编写我的后台

  1. 大部分的插件编写都是先从后台开始的,因为后台功能比较简单,无非就是“设置”和“管理”,就当热身了
  2. 说到“设置”,就不能不说 PwConfigSet 这个类库了,使用她,轻松搞定,别忘了 插件配置规范 哦
  3. 附后台源码
  1. ManageController.php 后台管理controller
  2. manage_run.htm 后台管理模板

编写底层服务

因为我要知道到底是谁动了我一下,所以我需要建一张表来记录这些数据,数据表设计如下,别忘了 数据库命名规范 哦:

CREATE TABLE `pw_app_dongta` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `act` tinyint(1) unsigned NOT NULL default '0',
  `touid` int(10) unsigned NOT NULL default '0',
  `created_userid` int(10) unsigned NOT NULL default '0',
  `creaed_username` varchar(15) NOT NULL default '',
  `created_time` int(10) unsigned NOT NULL default '0',
  PRIMARY KEY  (`id`),
  KEY `idx_touid_createdtime` (`touid`,`created_time`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
  1. 找到自动建立的Dao,Dm,Ds示例文件,发现文件名稍微不一样,没关系,改一下
  2. 接下来,就是coding,这里可以参考应用开发步骤。附底层服务源码,别忘了 类命名(文件名)规范 哦:
  1. App_Dongta_Dao
  2. App_Dongta_Dm
  3. App_Dongta

当然,在实际开发过程中,这一步很少能一口气写完的;没关系,需要的时候,回过头来继续完善。

编写我的前台主页面

哈哈,终于到了,最关键的地方了,这里就是各位自由发挥的地方了

  • 我的插件功能很简单,但是还是有几个地方不能忘记
  1. 后台设置了关闭,前台不能访问
  2. 我不允许未登录用户访问
//示例代码
if (!Wekit::C('site', 'app.dongta.ifopen')) { //应用是否关闭
	$this->showError('动他一下应用,关闭了');
}
if (!$this->loginUser->isExists()) { //应用是否登录
	$this->showError('login.not');
}
  • 继续coding,附源码
  1. IndexController.php 前台controller
  2. index_run 首页模板
  3. index_my 谁了我页面模板
  4. index_act ajax请求动作列表模板
  • 到此,我们的独立插件其实已经完成了,但是为了能更好地融入到系统中,我们还要添加两个钩子。【没错,抢占入口,就是抢占先机!】

添加Simple-Hook

  • 找到空间个人头像下面的钩子 s_space_user_info
  • 找到后台->云平台->应用管理->动他一下->设计->xml 在 inject-services 项下面添加
<s_space_user_info>
<app_dongta>
<class>EXT:dongta.service.srv.App_Dongta_Service</class>
<loadway>load</loadway>
<method>spaceButton</method>
<expression>config:site.app.dongta.space.ifopen==1</expression>
<description>动他一下空间按钮</description>
</app_dongta>
</s_space_user_info>
  • 完成 App_Dongta_Service 服务,附源码:
  1. App_Dongta_Service

添加Model-Hook

  • 找到帖子阅读页个人头像下面的钩子 m_PwThreadDisplay.createHtmlAfterUserInfo
  • 找到其业务流程类 PwThreadDisplay
  • 找到其扩展扩展服务接口基类 PwThreadDisplayDoBase
  • 继承基类,并实现相应接口,可选择实现,我们这里需要两个接口配合,分别是 createHtmlAfterUserInfo 和 runJs 接口
  • 代码实现,附源码 App_Dongta_ThreadDisplay
  • 该钩子的注册方式为
<m_PwThreadDisplay>
<app_dongta>
<class>EXT:dongta.service.srv.App_Dongta_ThreadDisplay</class>
<description>动他一下帖子页按钮</description>
</app_dongta>
</m_PwThreadDisplay>
但是,该注册方式注入的钩子是伴随PwThreadDisplay类的启动而自动启动的,所以一般用该方式注册的,都是偏内在逻辑处理的。显然,我们这里主要是展示内容的,这个我们就要用到我们下一个此类钩子的注册方式

添加Controller-Hook

  • 由于Model-Hook的自动启动特性,让重用一个业务流程变得困难
  • 自动注入的扩展类没有跟外部输入交互的能力
  • 所以为了解决这两个问题,就出现了Controller-Hook
  • 通常在实例化业务流程类时,会有如下类似代码
$threadDisplay = new PwThreadDisplay($tid, $this->loginUser);
$this->runHook('c_read_run', $threadDisplay);
  • 该钩子的注册方式为
<c_read_run>
<app_dongta>
<class>EXT:dongta.service.srv.App_Dongta_ThreadDisplayDoDongtaInjector</class>
<method>run</method>
<expression>config:site.app.dongta.read.ifopen==1</expression>
<description>动他一下帖子页按钮</description>
</app_dongta>
</c_read_run>
runHook就是将App_Dongta_ThreadDisplayDoDongtaInjector类中run方法生成的扩展服务类注入到$threadDisplay,注入后,跟使用 m_PwThreadDisplay方式是一样的
  • Controller-Hook中class的要求
  1. 必须继承PwBaseHookInjector,那么在这个类中就可以跟controller一样使用$this->getInput方法接收外部参数了
  2. 必须返回一个满足业务流程类需求的扩展服务类

终于完成了

关键词:phpwind

赞助商链接:

推荐文章