说明

WeiPHP 开发手册
说明

依照 WeiPHP 开发手册 http://www.weiphp.cn/wiki/ 制作

版本：20140522

制作：偶看

博客：http://www.oukan.net

如有任何问题欢迎反馈：oukan@126.com

Copyright 2014


功能介绍

WeiPHP 开发手册 简介 >
功能介绍

注意: 如果你有什么问题,可加入官方QQ群进行讨论: 329650736【已满】,8322255

一、简介

weiphp是一个开源，高效，简洁的微信开发平台，它是基于oneThink这个简单而强大的内容管理框架实现的。如你想深入理解和学习本开发平台，后续请研读oneThink的开发手册（http://document.onethink.cn/manual_1_0.html）

weiphp的目的是最大化的简化微信开发的流程，使用开发者能把最好的精力放到微信具体业务开发，并能以最快的时间完成。把一些常规而频繁的工作交由weiphp来处理即可。
为此weiphp提供了详细的二次开发文档，关键代码里还是相关的注释说明。weiphp采用插件的方式实现微信功能，不同的插件实现不同的微信功能，如下图所示就是weiphp前期自带的插件。

主要特性
1、基于oneThink 1.0正式版
2、开源免费，weiphp遵循Apache2开源协议,免费提供使用。
3、支持多用户多公众号管理
4、详细的二次开发文档，并不断更新增加相关开发案例提供学习参考
5、微信功能插件化开发，更易于定制和二次开发
6、提供丰富的微信插件下载安装使用，总有一些是符合或接近你的需求

主要功能
1、微信接口消息交互系统
2、微信插件管理系统
3、用户Passport系统
4、配置管理系统
5、后台建模系统
6、用户行为系统
7、系统日志系统
8、数据备份和还原
9、微信多用户多公众号管理系统
10、微信扫描登录

最低系统需求
PHP 5.3.0 或更高版本。
MySQL 5.0 或更高版本。

系统安装

1、将weiphp压缩包解压并上传到服务器。
2、首次在浏览器中访问index.php，将会进入安装向导。
3、按照安装向导完成安装。若在安装过程中出现问题，请访问官网讨论区寻求帮助。


架构设计

WeiPHP 开发手册 简介 >
架构设计

要了解weiphp的框架设计，需要从三个方面进行理解：一是代码的目录结构；二是weiphp执行的流程；三是微信交互的流程。

目录结构
由于基于oneTink，因此代码目录结构也与其一致：

├─index.php weiphp入口文件
├─Addons 微信插件目录（包括原oneThink插件，微信插件与它的区别看后续的说明）
│
├─Application 应用模块目录
│ ├─Admin 后台模块
│ │ ├─Conf 后台配置文件目录
│ │ ├─Common 后台函数公共目录
│ │ ├─Controller 后台控制器目录
│ │ ├─Model 后台模型目录
│ │ ├─Logic 后台模型逻辑目录
│ │ └─View 后台视图文件目录
│ │
│ ├─Common 公共模块目录（不能直接访问）
│ │ ├─Conf 公共配置文件目录
│ │ ├─Common 公共函数文件目录
│ │ ├─Controller 模块访问控制器目录
│ │ └─Model 公共模型目录
│ │
│ ├─Home Home 前台模块
│ │ ├─Conf 前台配置文件目录
│ │ ├─Common 前台函数公共目录
│ │ ├─Controller 前台控制器目录
│ │ ├─Model 前台模型目录
│ │ └─View 模块视图文件目录
│ │
│ └─User 用户模块（不能直接访问）
│ ├─Api 用户接口文件目录
│ ├─Conf 用户配置目录
│ ├─Common 后台函数公共目录
│ ├─Model 用户模型目录
│ └─Service 用户Service文件目录
│
├─Public 应用资源文件目录
├─Runtime 应用运行时目录
├─ThinkPHP 框架目录
└─Uploads 上传根目录
├─Download 文件上传目录
├─Picture 图片上传目录
└─Editor 编辑器图片上传目录

weiphp执行的流程

微信交互

1、用户与微信进行交互，交互的事件包括：回复公众号，扫描与公众号有关的二微码，关注（取消关注）公众号，在公众号里点击自定义菜单等
2、微信把用户的交互事件及相关参数传递给weiphp的微信接口（接口地址由weiphp提供并在公众号的微信管理后台里设置）
3、weiphp接收微信的请求，并把请求的xml转成数组形式提供后续功能使用，这部分处理代码 Application /Home/Controller/WeixinController.class.php,该文件是负责与微信交互的唯一接口。
4、weiphp判断请求的数据类型（如关注公众号还是回复公众号）进行相应的处理
5、如请求的数据类型是回复公众号，weiphp通过查询关键词表找出相应的插件名及具体的业务数据ID
6、通过插件名加载相应的插件，并把微信请求的数据和上一步通过关键词查出来的数据一并传递给到插件里。
7、由插件根据上面的请求数据处理具体的业务并组装返回数据
8、weiphp根据返回的数据再次封装成微信需要的格式并返回到微信里
9、微信根据返回的数据排版好显示给用户，如果返回的数据是带链接可点击的，进入下一步，否则到此为止
10、用户点击内容进入插件提供的地址对应的微网站页面（即3G页面）
11、用户可在微网站页面继续完成相应的业务操作，如投票，考试等，直到操作完成为止


谈谈开发目标

WeiPHP 开发手册 微信插件开发快速入门 >
谈谈开发目标

软件开发入门一般都有一个简单，易上手的案例教程，让大家更好，更快地了解其开发流程，WeiPHP也不例外，我们下面和大家一起开发一个简单的HelloWorld的微信插件，至于过程中配置的参数和原理什么的可以先不用关心，后续会有详细的说明。

HelloWorld实现的需求很简单，就是用户在公众号里回复：HelloWorld 这个词时微信自动回复： 欢迎您来到WeiPHP的世界 -_- 。效果如下图：

下面和我们一起来写这个插件吧


前期准备工作

WeiPHP 开发手册 微信插件开发快速入门 >
前期准备工作

以下准备工作是开发插件前必须配置好的，当然不是每次开发插件都需要进行这一步，如果之前已经配置过，可略过此步。

a、在你的服务器上安装weiphp，weiphp下载地址是： http://www.weiphp.cn
b、在微信公众平台注册一个公众号，无论是订阅号还是服务号都可以，微信公众平台地址：https://mp.weixin.qq.com
c、在WeiPHP里增加公众号： 第一次登录WeiPHP的管理中心时，系统会要求增加公众号，如果之前已经增加，请忽略此步。增加公众号页面前面三项内容是你在微信公众平台里的信息，不懂可以点这里看看 。
d、微信公众平台配置接口： 上面配置完公众号之后，在自动返回的公众号管理列表中点击“接口配置”，按照页面的提示配置好微信公众平台


第一步：增加插件

WeiPHP 开发手册 微信插件开发快速入门 >
第一步：增加插件

直接在浏览器里输入后台地址登录： http://你的网站地址/index.php?s=/admin （如： http://www.weiphp.cn/index.php?s=/admin）

登录管理平台后，进入：插件管理==》微信插件==》快速创建 进入创建插件页面

(这里请注意是点击在微信插件页面里的快速创建，而不是下面插件管理里的)

在创建插件页面输入以下的参数(请注意标识名中的大小写)：

主要填写标识名和插件名即可，其它默认即可。填写完点确定按钮提交。页面自动进入微信插件列表，然后点击“安装”上面的插件

点击安装完成后，至此后台插件增加完成


第二步：编写微信响应代码

WeiPHP 开发手册 微信插件开发快速入门 >
第二步：编写微信响应代码

在上面增加完成插件后，系统会自动在 Addons 目录下创建了HelloWorld插件所需的目录结构和相关基本文件，如
打开 Addons/HelloWorld/Model/WeixinAddonModel.class.php 文件（每个微信插件都有这个文件）。把replay方法里的内容清空然后增加下面的语句：

$this->replyText('欢迎您来到WeiPHP的世界 -_-');

效果如下图所示：

至此代码增加完毕。您也许会说：“哇，就修改一行代码？！！”。是的，就这么简单。这就是我们的目标：快速开发微信插件。


激动的时刻：测试体验

WeiPHP 开发手册 微信插件开发快速入门 >
激动的时刻：测试体验

在绑定的公众号里输入“HelloWorld”或者 “微信示例”看看效果吧（见下图），也许你会问，输入的词不正是上面增加插件时填写的标识名和插件名吗？恭喜，你答对了-_-


开发流程

WeiPHP 开发手册 微信开发流程及关键点 >
开发流程

通过上面简单的HelloWorld微信插件的开发案例，可以总结微信插件开发出下面的几点：

1、准备工作前的公众号配置，现在市面上无论哪个微信营销平台都会有这一步，大同小异而已，这部分在上面已经说得很清楚，在此不再详明。

2、后台增加微信插件：得益于oneThink内容管理系统的强大插件功能，插件的创建直接在后台完成，并且自动生成相应的插件目录和文件，下面以投票插件为例解说其目录结构：

├─Addons 插件库（包括微信插件和原oneThink插件在里面）
└──Vote 投票插件标识
├─Controller 插件控制器目录
└──VoteController.class.php 投票处理主程序 投票列表，增，删，改和手机端投票的功能都在这个文件里实现
├─Model 插件模型目录
├──VoteOptionModel.class.php 投票选项模型
└──WeixinAddonModel.class.php 投票与微信交互的模型文件
├─View 插件视图文件目录
└──default 视图默认风格
└──Vote 对应着上面VoteController.class.php方法里的模板
├──add.html 增加投票模板
├──edit.html 编辑投票模板
├──lists.html 投票管理列表模板
└──show.html 手机端投票模板
├─config.php 插件配置文件
└─VoteAddon.class.php 插件文件

由上面的目录结构和一般的thinkphp项目是一样的，只是里面有些地方有点不一样，后面几个关键词就是主要说明其不同的地方。


插件控制器部分

WeiPHP 开发手册 微信开发流程及关键点 >
插件控制器部分

如果微信插件仅仅简单的逻辑处理，没有动态数据的增、删、改、查操作，这部分都是可以不要的，甚至可以删除掉，如上面的HelloWorld插件，就不需要用到控制器这部分。

最简的控制器文件代码结构如下：
先命名空间和使用AddonsController控制器，注意微信插件里所有的控制器都需要继承AddonsController，否则无法在浏览器里通过URL访问到它。

需要在获取访问插件控制器的地址，可以通过 addons_url函数生成，例如下图：

上图中生成的$url 变量就是访问投票插件（Vote://）中的VoteController.class.php文件里的show方法，同时带三个GET参数进来

AddonsController控制器不仅提供了浏览器通过URL访问插件控制器的方法，还提供了与插件标识名相同的数据模型（如果后台有增加的话）的常用操作和对应的HTML模板，包括列表管理（lists）、增加（add）、删除（del）、修改（edit）、配置（config）等操作。
即在一般一个插件对应一个数据表的情况下，你基本可以不增加一个代码，就可以在WeiPHP前台对数据进行常规管理和维护，极大减轻了开发人员的负担。后续的复杂微信插件开发案例有这部分的使用例子。

如果AddonsController控制器提供的常用操作不能满足业务需求，可以在插件控制器里重写相应的方法来覆盖AddonsController控制器的方法即可。
如在投票插件里，因为增加一个投票时不仅仅要把信息保存到投票数据表（wp_ovte）中，还增加把选项信息也保存到投票选项表中（wp_vote_option），所以在我们的VoteController.class.php重写了lists、add、del、edit方法，当然也新增加了其它几个业务需要的方法

在你看VoteController.class.php代码之前，你首先需要了解oneThink封装的强大而易用的模型管理功能，功能的使用可参考oneThink的手册：

模型管理：http://document.onethink.cn/manual_1_0.html#onethink_usehelp_model
独立模型：http://document.onethink.cn/manual_1_0.html#onethink_2_7

所谓的模型管理，我们的理解就是一般情况下一个模型对应一个数据表（也可能是多个数据表），而这个模型已经封装好了对这个数据表的一些常用的操作和模板，如增加数据的表单页面，管理数据的列表页面等都封装了通用的操作和页面。
开发者只需要在后台把模型的参数配置好就OK，省去了自己写处理程序和设计模板，JS控制，表单验证等繁琐而重复的工作，而且代码少还容易维护，因此这很有必要学习怎么用它。当然如果你不想学习，也是可以直接按你自己的方式在插件
控制器里完成你的业务需求的。

在插件控制器里和在应用里（Application目录下 ）控制器里开发大部分都是一样，区别主要在下面几个地方，开发过程一定要注意

1）控制器里的常量
在应用里，MODULE_NAME、CONTROLLER_NAME 、ACTION_NAME，分别代表组名、控制器名、方法名
但在插件里，因为插件的访问是通过home/addons/execute这样的方式间接访问，因此MODULE_NAME、CONTROLLER_NAME 、ACTION_NAME这三个常量都是固定为home、addons、execute
这不与插件控制器对应起来，因此在插件里。增加了_ADDONS、_CONTROLLER、_ACTION来分别代表插件标识名、插件控制器名、插件控制器方法名

上面的理论有点绕，直接来看看下面的访问投票列表管理页面的地址：
http://www.weiphp.cn/index.php?s=/home/addons/execute/_addons/vote/_controller/vote/_action/lists.html

该地址访问的是 Addons/Vote/Controller/VoteController.class.php里的lists方法，那么它对应的常量值应该是这样的：

MODULE_NAME： Home
CONTROLLER_NAME ： Addons
ACTION_NAME： execute
_ADDONS： Vote
_CONTROLLER： Vote
_ACTION： lists

2)插件里的模板定位
由于系统真实的控制器是home/addons/execute，因此要在oneThink原系统中访问插件目录下的View里的模板，你需要自己先找出模板的地址，然后再调用dispaly方法进行渲染模板，如：
$this->display ( T ( 'Addons://Vote@Vote/lists' ) );

但这样的方式总感觉不大方便，因此WeiPHP直接在AddonsController控制器里重写了display方法，开发者可以像在应用里一样使用display方法，不再需要先找出模板地址，上面的方法可以简写成：
$this->display ( );
或者 $this->display (‘lists’);
或者 $this->display ( 'Vote/lists' ) );


插件模型部分

WeiPHP 开发手册 微信开发流程及关键点 >
插件模型部分

该模型操作和应用里的模型操作是一样，都是同样继承Model基类，因此它没有什么不同的地方，主要区别在于它的调用方式稍有不同，例如实例投票插件里的投票选项模型的方法是：
D ( 'Addons://Vote/VoteOption' )

不知大家是否注意到，每个微信插件的模型都会有一个WeixinAddonModel.class.php文件，这是这个插件之所以存在的灵魂文件！因为它是负责与微信交互的窗口。一般来说，微信请求WeiPHP时，在Application/Home/Controller/WeixinController.class.php这个微信交互中心里进行数据加工和功能分发，其中数据加工就是把微信传过来的xml转成数组（数组变量为$dataArr），并获取相关的关键词数据（如果有关键词的话，其数组变量为$keywordArr）；而功能分发就是根据相关规则（见下图的分发规则）找到相应的插件，最后加载这个插件下面的WeixinAddonModel.class.php文件，并调用里面的replay方法进行业务需要的加工处理，例如上面的HelloWorld插件就是直接返回一句话

而在投票的插件中，则相对复杂些，它需要返回一个投票的图文信息


插件视图部分

WeiPHP 开发手册 微信开发流程及关键点 >
插件视图部分

该部分与应用里的视图是一样的，没有特别的地方


插件配置文件

WeiPHP 开发手册 微信开发流程及关键点 >
插件配置文件

如果插件有需要配置的，如智能聊天插件（Chat）需要在前台配置公众号的聊天机器人参数

它的配置文件如下

值得注意的是，插件的配置参数有三个保存的地方，首先是 config文件里配置的默认参数（value值），然后是在后台里的插件配置（见下图），后台配置的数据保存到wp_addons数据表的config字段中

最后是前台公众号里的功能配置，如下图，这里的值会保存到wp_member_public数据表的addon_config字段中

其取值的优先级刚好相反，则先取公众号的功能配置，如果没有配置，就取后台的插件配置，如果插件配置也没有值，就取配置文件里的默认参数。
当然对于开发来说，只需要知道其取值优先级即可，因为WeiPHP已经把取值封装成了函数getAddonConfig，只需要把插件标识名传进去即可，使用非常方便，如在智能聊天中是这样取值的：

扩展: oneThink关于配置文件的说明
http://document.onethink.cn/manual_1_0.html#onethink_3_5_5


插件信息文件

WeiPHP 开发手册 微信开发流程及关键点 >
插件信息文件

在微信插件里，这个自动生成的插件信息文件基本不需要修改。所以在此不详述


谈谈开发需求

WeiPHP 开发手册 微信插件开发高级案例 >
谈谈开发需求

注：该案例插件的代码可以加入官方群（329650736【已满】,8322255）里的群文件里下载

建立一个建议意见反馈的插件，用户在微信里输入“建议意见”四个字时，返回一个图文信息，引导用户进入填写建议意见的3G页面，用户填写信息提交后显示感谢之意并提示关闭页面返回微信
管理员可以在管理中心里看到用户反馈的内容列表，并对内容进行编辑，删除操作


数据结构分析

WeiPHP 开发手册 微信插件开发高级案例 >
数据结构分析

根据上面的需求，我们知道需要一个数据表来保存用户反馈的内容。因此我们需要以下数据结构：
id: 自增长的关键编号
uid: 当前用户的ID
content: 用户反馈的内容
cTime: 创建的时间

为了防止各个微信插件都需要处理或者保存各自的用户信息，WeiPHP对于微信用户在关注公众号时自动注册一个用户ID，即uid。如果微信插件需要保存用户的信息的，可以把用户数据都保存到统计的用户信息表中（wp_member）。在建议意见这个微信插件里，我们特意加了可以让用户输入姓名、手机号码的输入项，但我们不需要保存到建议意见的数据表中，我们它保存到wp_member数据表就行。因此在建议意见的数据表中只需要保存uid即可

至于创建的时间保存的是一个时间戳，这样方便操作。到时在显示时间的地方只需要使用 time_format 这个函数转换成可读的格式即可


前期准备工作

WeiPHP 开发手册 微信插件开发高级案例 >
前期准备工作

同HelloWorld微信插件开发中的准备工作一样，如果之前已经做过，可略过。


创建数据模型

WeiPHP 开发手册 微信插件开发高级案例 >
创建数据模型

登录后台，进入：系统==》系统设置==》模型管理==》新增 (如下图)

在新增的表单里输入下面的内容，然后确认提交

增加成功后页面会自动跳转到模型管理的列表，我们新增加的模型就在最上面第一个，接着点击“编辑”==》“设计”==》“管理”进入编辑页面，如下图

在管理页面里分别新增加三个字段（注意，id字段模型会自动创建，在这里不需要再重复增加）

增加uid字段 ，字段类型为数字。因为这个字段是系统自动赋值，不需要用户输入，所以在“是否显示”选择不显示，在高级里的“自动完成方式”选择函数，完成规则是：get_mid

扩展知识：get_mid这WeiPHP预先写好的函数，如果想要知道WeiPHP预先都写好了哪些函数。可以直接查看 Application\Common\Common\function.php 这个公共函数库，当然开发者也可以在里面写入自定义的函数供自己使用。这些函数会在WeiPHP加载时自动加载进来，可以在应用或者插件的任何地方调用。

接着增加内容字段，字段类型选择文本框，是否必填那里选择是，高级的里选项默认即可

最后增加创建时间字段，字段类型选择时间，是否显示选择不显示，在高级里的自动完成方式选择函数，完成规则：time 自动完成时间选择新增即可

上面都完成后返回列表如下图所示，模型字段增加完毕。

接着配置模型的列表

重新进入建议意见的模型管理的编辑模型页面里的设计页面

最下面的列表定义和默认搜索字段配置成下图所示

列表定义的内容：

uid:姓名
content:内容
mobile:联系方式
cTime|time_format:创建时间
id:操作:[EDIT]&id=[id]|编辑,[DELETE]&id=[id]|删除

在上面的列表内容里，我们使用了get_truename、time_format这些函数对表单的数据进行处理，开发者也可以使用其它函数，当然前题是这些函数已经存在并可以正常调用。
如在开发这个插件时，get_truename这个函数在WeiPHP里还没有定义过，因此我们需要在插件里进行定义。

如果你不明白上面列表定义的内容，可以点击这里查看更多说明：
http://document.onethink.cn/manual_1_0.html#onethink_usehelp_model

上面两项增加完毕，其它选项和内容保存默认保存即可，至此模型创建完毕，你的数据库应该会自动生成了一个suggestions的数据表


创建微信插件

WeiPHP 开发手册 微信插件开发高级案例 >
创建微信插件

进入后台：插件管理==》扩展==》微信插件==》快速创建 的页面，填写下图的内容

基中标识名、插件名、描述都是根据插件实际情况填写，而版本，作者这两项默认即可，无关重要。
要勾先安装后是否启用和是否需要配置，而配置的内容需要输入复制内容：

<?php
return array (
'need_truename' => array (
'title' => '是否需要填写昵称:',
'type' => 'radio',
'options' => array (
'1' => '是',
'0' => '否'
),
'value' => '0'
),
'need_mobile' => array (
'title' => '是否需要填写手机号:',
'type' => 'radio',
'options' => array (
'1' => '是',
'0' => '否'
),
'value' => '0'
)
);

如果你不明白上面的配置的意思，可以在这里查看更多信息：
http://document.onethink.cn/manual_1_0.html#onethink_3_5_5

上面的信息填写完毕后点击确定保存信息，然后在自动返回的微信插件管理列表中点击安装，至此插件创建完毕。


插件功能开发

WeiPHP 开发手册 微信插件开发高级案例 >
插件功能开发

经过上面第4步的插件创建后，在Addons目录下自动创建一个名叫Suggestions的插件目录，这时插件已经具备了基础微信插件的功能。

如数据管理列表功能

还有功能配置管理

插件功能开发之控制器部分

打开 Addons\Suggestions\Controller\SuggestionsController.class.php
在该文件里可以看到它继承了Home\Controller\AddonsController，而AddonsController里已经预先把列表管理、增加、删除、配置等通用功能写好，乐观的情况下你可以不写一行代码即可完成数据的管理操作。

但因为建议意见涉及到用户数据，需要从suggestions和member两个数据表里取数据进行处理，因此它需要重写父级的lists方法进行取数据，而它的删除直接用父级的del方法就行

先在SuggestionsController.class.php 增加一个lists方法，内容如下：

因为公共的模型信息里带有前台列表显示需要的list_grids参数，因此直接前面两部分（获取模型信息和获取模型列表数据）直接调用即可。从变量list_data里可以得到：
list_grids：列表要显示的字段信息
list_data ：列表要显示的数据
_page ：列表的分页HTML代码

获取相关的用户部分则是把得到的list_data数据里补充上用户姓名，联系方式。
最后调用模板输出。

扩展知识：原则上来说，lists方法里的处理程序完全可以用自己的风格编写，它的作用是取从数据库取数据，组装成网页需要的格式就行。上面的列表使用的网页模板是公共的通用模板，因此它需要传递list_grids这个变量。其实在这里开发者也可以使用自己的模板。如后面的在手机里显示表单的处理方法就是使用了自己开发模板，详情可见后部分

至此列表的功能开发完毕，到现在为此，列表页面上的增加、删除、编辑的功能直接使用父级的通用功能实现就行，因此在SuggestionsController.class.php文件不再需要再增加一行就可以实现这三个功能。不信可以在网页上试试-_-

上面部分已经实现了PC端的全部操作，因此接下来就要实现手机端的功能

当用户在微信公众号里输入“建议意见”时，需要返回一个图文信息引导用户进入填写内容的3G页面，因此首先要配置返回的图文信息：
打开 Addons\Suggestions\Model\WeixinAddonModel.class.php 文件，在repay方法里增加以下代码

$param ['token'] = get_token ();
$param ['openid'] = get_openid ();
$url = addons_url ( 'Suggestions://Suggestions/suggest', $param );
$articles [0] = array (
'Title' => '建议意见',
'Description' => '请点击进入填写反馈内容',
'PicUrl' => 'http://weiphp.cn/Public/Home/images/about/logo.jpg',
'Url' => $url
);
$res = $this->replyNews ( $articles );

具体效果如图

上面就是返回图文信息的全部代码，里面的标题、描述、图片都是固定的。当然你也可以做成配置的方法实现，具体的配置实现方法可以参考“欢迎语”的微信插件里的代码。

当用户在微信里得到图文信息时，点击进入一个填写反馈内容的3G页面。所以接下来还要回到 Addons\Suggestions\Controller\SuggestionsController.class.php 文件里
接着在这文件里增加以下方法

因为我们这个插件有配置用户在反馈内容时是否填入姓名，是否输入手机号，因此首先先获取配置，每个插件都可以通过 getAddonConfig('插件标识名') 这样的方式获取自己的配置参数（当然前提是有配置参数）
接下来用IS_POST判断是用户已经在提交数据还只是刚进入页面，如果是提交数据，则是组装并保存到数据库里，因为比较简单，在这里没有用到模型的方式保存数据了，如果要做到程序的健全性，当然还需要加一些安全过滤和不为空的判断，或者直接使用模型提供的方式进行数据增加，因为在模型里自动对数据进行过滤，验证和补充的。

如果是刚进入页面，直接使用display 渲染模板。在这里要注意的是，像上面的增加、编辑甚至列表的页面，模板都是使用公共的模板。但因为suggest不在公共方法里，还有业务的需求用公共的模板实现也不大好看。因此我们使用自定义的模板。

打开 Addons\Suggestions\View\default\Suggestions 目录，在这里增加一个名为 suggest.html 的模板文件。
并在 Addons\Suggestions\View\default 目录再创建一个名为 Public 的目录用来存放 模板中需要的css,js和图片文件模板
模板代码见下图

这是一个普通的表单模板，它先加载一个3G页面的公共头部文件，这个文件位于 Application\Home\View\default\Public 目录下面，有兴趣的开发者可以打开看下，它加载了常用的jquery、css文件
该页面需要的自定义的css和图片就放到上面创建的 Addons\Suggestions\View\default\Public 目录下，调用的路径使用 ADDON_PUBLIC_PATH 即可指向Public目录下

具体的css和图片文件可以从后面下载案例文件里看到

至此全部功能就完成了90%了，剩下就是处理插件的打包安装功能


插件打包测试

WeiPHP 开发手册 微信插件开发高级案例 >
插件打包测试

如果插件没有用到模型数据，如上面的HelloWorld插件，打包的方法就是直接把 Addons 目录下的HelloWorld插件目录拷出来即可在别的WeiPHP系统里安装使用，比较方便。

如果插件有用到模型数据，就需要行把模型数据分别导出成安装文件（install.sql）和卸载文件（uninstall.sqll）放到插件根目录下了，具体操作看下面。

进入后台：系统==》系统设置==》模型管理

分别点击导出安装文件和导出卸载文件链接，并把导出的两个文件保存到 Addons\Suggestions 插件根目录下。
如果开发者开发的插件除了模型的数据，还有其它数据也需要安装时，自行在install.sql和uninstall.sql里增加相应的SQL就行。
插件在后台安装里会加载install.sql进行数据初始化，而在卸载时会执行uninstall.sql进行数据清理

至此插件开发完毕，把它放到服务器上安装插件后，最终的效果


WeiPHP是如何调用你的插件的

WeiPHP 开发手册 二次开发专题学习 >
WeiPHP是如何调用你的插件的

作为开发者，最关心莫过于在WeiPHP框架里是如何调用在众多的插件中选择并调用（统称定位，下同）其中的一个插件的。首先我们来梳理下微信的用户情景：

场景一

假设管理员提前创建了一个投票，并设置这个投票的关键词是“大会投票”。
当用户在微信里输入“大会投票”时，微信就返回上面的投票的图文信息。用户点击这图文信息就可以进入投票的页面

总结：这个一种关键词完全匹配的场景，一个关键词对应一条具体的信息。

场景二

假如有一个天气的插件
用户输入“北京天气”
微信回复当天北京具体的天气信息
用户输入“深圳天气”
微信回复当天深圳具体的天气信息

或者

有一个上墙的功能，要求输入 “##+聊天内容”就可以在大屏幕上显示
用户输入“##我觉得WeiPHP入门比较简单”
大屏幕上就显示用户名和这句话“我觉得WeiPHP入门比较简单”

总结：这是一种关键词模糊匹配的场景，关键词包含在其中（当然关键词也可能在中间或者最后），除去关键词的内容作为具体的业务数据。先是关键词负责定位到插件，然后插件再利用业务数据处理并返回相应的内容

场景三

假设有一个活动需要报名，报名入口的关键词设置为“报名”
用户输入“报名”
微信回复“欢迎您报名XX活动，请回复姓名+手机号码完成报名，如： 李某某 18688969945”
用户输入：“韦小宝 15011253000”
微信回复："报名成功”

或者

假设有一个机器人学习的插件
用户输入：“机器人学习时间”
微信回复：“你的问题是？”
用户输入：“这个世界上谁最美？”
微信回复： “你的答案是？”
用户回复： “当然是你啦！”
微信回复：“我明白啊，不信你可以问问我”
用户回复：“这个世界上谁最美？”
微信回复：“当然是你啦！”

总结：这是一种关键词加引导输入的场景，用户两次输入的内容是有关联关系的。

场景四

用户关注公众号
用户取消关注公众号
用户扫描带参数二维码
用户上报地理位置
用户点击自定义菜单

总结：这是微信固定的用户事件，提前可以预知

架构分析和开发实例

通过上面四种场景总结分析，WeiPHP关于每个场景的实现方案如下

场景一
这是关键词完全匹配的场景，在WeiPHP里，完全匹配的关键词（也叫精准关键词，下同）有两种，一种是由所有安装过的插件标识名（英文名）和插件名（中文名）组成的插件关键词组，另一种是由数据库里的关键词表（wp_keyword 且 type=0）里的关键词组成业务关键词组。而在定位过程中先定位前者，前者不匹配再取后者。值得注意的是，关键词表里的type是关键词类型，值默认为0，表示是精准关键词；值为1是表示模糊关键词

精准关键词的匹配算法：

场景二
这是关键词模糊匹配的场景，在WeiPHP中，模糊关键词保存在关键词表里（wp_keyword 且 type=1）。它有两种类型，一种是token=0的插件初始化模糊关键词，所有的公众号都可以使用，如上面的天气插件，就可以设置“天气”的关键词，并把token值设置为0即可；另一种是公众号在运营过程中产生的模糊关键词，具体的使用就由开发者自己发挥了

模糊关键词的匹配算法：

场景三
这是一种关键词加引导输入的场景，在WeiPHP中，第一次输入关键词词（可以是精准关键词也可以是模糊关键词）定位到插件后，在插件的具体处理中可以设置一个用户状态，也就是把当前的插件名，具体业务参数缓存过来，当用户再次回复信息时，优先判断这个用户状态是否存在，如存在就直接读取缓存里的插件信息，并再次进入该插件继续之前的业务处理，值得注意的是，用户状态只能用一次，用完就失效，要连接多次使用是（如上面 的机器人学习插件），就需要在每次回复前都设置一次用户状态。

在WeiPHP核心里的引导代码：

其中用户状态变量是 user_status_uid 这个uid就是当前用户的ID，第个用户都不一样
用户状态是使用S函数进行缓存的，因此开发者在插件里设置状态也需要使用S函数进行设置
用户状态缓存的数据结构是：

array (
'addon' => '插件标识名',
'keywordArr' => array ('插件需要的各种参数集合组成的数组，如不需要为空即可')
);

场景四
这个比较简单，就是用户在执行这个操作时，WeiPHP会循环全部安装的插件，如果插件里的WeixinAddonModel.class.php文件实现了该事件的方法，就直接调用实现。
微信的事件对应的方法有：

* subscribe : 关注公众号
* unsubscribe : 取消关注公众号
* scan : 扫描带参数二维码事件
* location : 上报地理位置事件
* click : 自定义菜单事件

开发者只要在插件的WeixinAddonModel.class.php里实现上面的方法，当用户触发相关事件时，就能启用所有插件里关于这个事件的处理方法。

如在微信用户中心插件里实现的用户关注时自动初始化一个用户信息:


WeiPHP公众号权限控制介绍

WeiPHP 开发手册 二次开发专题学习 >
WeiPHP公众号权限控制介绍

公众号权限控制是主要指控制公众号能使用哪些插件，不能使用哪些插件。在WeiPHP中，控制的原则是无禁止即可用，这样安装完插件后即可马上使用，省去还要配置权限或者因权限配置不当导致不能使用的麻烦。

公众号权限的控制思路：一个公众号对应一个公众号等级===》一个等级可配置可使用哪些插件===》公众号通过关联的等级取得可使用的插件列表

1、公众号等级管理

因此在WeiPHP里，首先需要配置公众号的等级

增加或者编辑等级：

用户可以根据自己的需求定义好听的等级的名称和这个等级有哪些插件可使用

等级配置完后还需要配置一个新的公众号注册时默认分配的等级

配置的等级ID可以从公众号等级管理列表中得到，系统默认为0，即公众号不在等级权限控制中，它拥有全部插件的使用权限。

值得注意的是：在运营过程中，如果管理员要删除一个公众号数不为0的等级，删除后之前在这个等级下的公众号的等级自动变成上面配置的默认等级

2、公众号管理

配置完等级后，接下来需要配置公众号的等级

从公众号编辑进入

在编辑页面即可对公众号的等级进行更改

至此公众号权限配置介绍完毕，下面对于开发者我们再深入了解下权限控制的原理

3、权限控制的效果

上面两步是配置等级和公众号等级分配，这些都是看得到的功能。作为开发者，可能对在哪里控制感兴趣。

因此我们先来回顾下权限控制的目的：控制某个公众号是否有权限使用某个插件

由目的可知我们需要控制的场景：

a、管理中心的功能设置里公众号对没有权限的插件不能启用，而且左侧栏的插件功能列表也不显示无权限的插件

b、在插件启用（或禁用）功能里加权限判断，即使用户伪造一个启用的地址企图启用无权限的插件时也无效

c、在微信交互中心里对插件也进行权限判断，对于无权限的插件直接过滤掉，包括在数据库查关键词对应的记录时也加上插件过滤条件


WeiPHP开发中的调试方法介绍

WeiPHP 开发手册 二次开发专题学习 >
WeiPHP开发中的调试方法介绍

在二次开发，会经常遇到各种各样的问题，这时就需要一些调试方法来定位问题。

在WeiPHP中有三种调试方法：开启调试模式、查看微信交互日志，使用微信公众平台提供的调试工具进行调试。下面对这三种方法进行详述。

一、开启调试模式

在PC端开发中，作为开发者一般建议是要把调试模式打开的。因为WeiPHP安装包默认是把此模式关闭，导致经常有开发者在官方QQ群里发一个报错的页面，但这个报错的页面只能告诉大家有错误，却没有提示具体是什么错误，发给别人看也没有什么意义，在这时只能先让开发者把调试模式打开，再看看调试打开时页面错的具体错误，这样才能对症下药。打开方法：

1、把根目录下的入口文件 index.php 打开，把 APP_DEBUG 常量设置为 true，效果如下图：

2、如果还需要显示程序运行的信息，可以在后台把trace打开就行

打开Trace后就可以看到这样的信息

点击右下角的图标后就可以看到具体的消息

二、查看微信交互日志

在开发微信功能时，有时会出现没有返回数据的时候，这时首先可以看看交互日志

为了防止文件可写权限等问题导致无法写日志的问题，微信的交互日志记录直接记录在数据库的weixin_log数据表里

一般交互日志记录两条数据，一条是微信的原始请求数据，一条是WeiPHP给微信响应的回复信息，data_post等于_replayData就表示是回复的记录
如下图的微信的原始请求数据，调试过程中发现能正常增加这条日志，说明微信已经正常把数据发送到WeiPHP里，至少微信与WeiPHP之间的通信是没有问题的了

接下来看看上面的请求有没有相应的的响应回复日志，如果有这条日志，还要看看日志里回复的内容是否与预期的内容一致。如果没有这条日志，说明程序在处理过程哪里不对导致中断了

至于程序中断的位置，开发者可以使用 addWeixinLog 这个公共函数在程序运行的过程中记录日志，一步一步进行记录日志进行跟踪，如HelloWorld插件可以加这样的调试

三、使用微信公众平台提供的调试工具进行调试

上面第二种方法如果还调试不出什么问题，这就需要使用微信提供的调试工具了。但因为微信调试工具需要一些参数还是需要从我们的日志表中获取，具体操作如下

1、进入调试工具页面

2、以消息接口调试为例，调试页面如下：

参数列表的数据来源说明：

URL: 从微信公众平台的开发模式页面里可以得到，如下图：

剩下的ToUserName、FromUserName、CreateTime、MsgId这几个参数可以从我们的日志随便找一条微信请求的数据进行复制
如下图的日志可知这几个值是
ToUserName： gh_1529be6d4b33
FromUserName oDQVqt54_P9Py5rApEVgmvMCD784
CreateTime 1395972290
MsgId 5995655331872296963

而最后的Content 的值肯定是根据开发者自己的需求随意填写了

使用微信调试工具，可以直接看到WeiPHP返回的数据，特别是有错误，在日志里是看不到，但这里就可以直接看到了。

最后综上所述，上面的三种调试方式都是各有用途，开发者可以根据具体场景进行使用。开发过程中或者开发完，可以把日志表的数据全部清空，不影响功能的使用。