上一次介绍了如何在weiphp中开发自己的第一个功能插件 “Hello Wordl” 。我们介绍说,开发完成后,在前台添加的微信公众号里回复插件名称,就可以收到微信返回的 “Hello World” 字样。大家或许有疑问,我并没有在前台设置关键字,也没有添加关键字配置,为什么回复了插件名,就可以自动触发这个插件呢?不用着急,这一节我讲介绍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 编辑器图片上传目录
这一节我们主要关注Home文件夹,打开Home文件夹,我们找到前台控制器目录,即Controller目录,这个目录是前台的控制器目录,里面有一个WeixinController.class.php,这个就是微信的交互控制器,我们今天讲到的关键字分发和后面讲到的消息分发,都在这个文件里完成。
跳过index方法我们直接查看reply方法,在这个方法中,官方给了较为详细的说明,有耐心的同学可以仔细的看一遍。我先描述一遍关键字的分发过程,然后我们再一起往下看,这里的关键字分发过程是这样的:
后台收到用户消息后,首先使用消息内容匹配插件名,如果匹配到,则调用匹配到的插件处理消息,如果没有匹配到,则通过消息内容精确匹配已经设置的关键字,匹配到则处理,没有匹配到,则通过消息内容模糊匹配设置好的关键字,匹配到则处理,如果还是没有匹配到,那就无能为力了,如果这时候开启了智能聊天功能那就不用担心,weiphp会在以上匹配都失败的情况下,自动调用智能聊天插件来处理用户消息。
以上过程精简一下:先用消息内容匹配插件名,如果没有匹配到,再用消息内容匹配关键字,如果没有匹配到,则默认调用Chat(智能聊天机器人)处理消息。
好了,到这里,关键字的匹配和分发就清楚了,在程序源码中也有依次的对应,可以看reply中的程序段:
// 通过插件标识名、插件名或者自定义关键词来定位处理的插件 if (! isset ( $addons [$key] )) { foreach ( $addon_list as $k => $vo ) { $addons [$vo ['name']] = $k; $addons [$vo ['title']] = $k; $path = ONETHINK_ADDON_PATH . $vo ['name'] . '/keyword.php'; if (file_exists ( $path )) { $keywords = include $path; if (isset ( $keywords [$key] )) { $addons [$key] = $k; $keywordArr = $keywords [$key]; } } } }
// 通过精准关键词来定位处理的插件 token=0是插件安装时初始化的模糊关键词,所有公众号都可以用 if (! empty ( $forbit_addon )) { $like ['addon'] = array ( 'not in', $forbit_addon ); } $like ['token'] = array ( 'exp', "='0' or token='{$this->token}'" ); if (! isset ( $addons [$key] )) { $like ['keyword'] = $key; $like ['keyword_type'] = 0; $keywordArr = M ( 'keyword' )->where ( $like )->order ( 'id desc' )->find (); addWeixinLog ( M ()->getLastSql (), 'addon1' ); if (! empty ( $keywordArr ['addon'] )) { $addons [$key] = $keywordArr ['addon']; $this->request_count ( $keywordArr ); } }
// 通过模糊关键词来定位处理的插件 if (! isset ( $addons [$key] )) { unset ( $like ['keyword'] ); $like ['keyword_type'] = array ( 'gt', 0 ); $list = M ( 'keyword' )->where ( $like )->order ( 'keyword_length desc, id desc' )->select (); foreach ( $list as $keywordInfo ) { $this->_contain_keyword ( $keywordInfo, $key, $addons, $keywordArr ); } } addWeixinLog ( M ()->getLastSql (), 'addon2' );
// 以上都无法定位插件时,如果开启了智能聊天,则默认使用智能聊天插件 if (! isset ( $addons [$key] ) && isset ( $addon_list ['Chat'] )) { // 您问我答插件特殊处理 $YouaskServiceconfig = getAddonConfig ( 'YouaskService' ); // 获取后台插件的配置参数 if ($YouaskServiceconfig ['state'] == 1) { $addons [$key] = 'YouaskService'; } else { $addons [$key] = 'Chat'; } }
以上都明白了,我们来做一个实验,既然默认没有匹配上的时候调用Chat(智能聊天机器人)插件来处理消息,那么我们可不可以让它默认用我们自己的插件来处理呢?当然是可以的,昨天我们写了一个Example插件,用于输出Hello World字样,今天我们用它来输出更多的东西,让它更自由,怎么做呢?很简单,请看下面。
既然我们知道weiphp默认是使用Chat插件来处理消息的,那么我们只需要将Chat改为我们自己的插件不就可以了?所以,我们需呀修改一行代码:
$addons [$key] = 'Chat';
改为:
$addons [$key] = 'Example';
Example就是我们昨天创建的插件的标示名称。好了,保存你的代码,记得确保服务器上的也修改了,马上我们就可以看到激动人心的一刻。打开你的微信,打开你设置的微信公众号,昨天我们只能通过回复插件名或者插件标识名才可以收到HelloWorld的字样,现在你可以试试,随便输入什么,看它如何回复你。
具体的效果我就不贴图了,大家可以自己测试,明天我将介绍weiphp中的消息体,一起如何让它向你回复语音识别后的内容。