欢迎关注我的微信公众账号“APP每日推荐”
推荐一些精彩手机应用,互联网行业资讯~
<!--题外话 :做这样一个系列的原因在于,这个微信公众平台算的上是我解除编程一来开发的第一个有实际用途的东西,在这之中有很多体会,不敢说讲给大家听,只是同大家分享一下,作为学计算机的,因为专科学的是网络,所以编程解除的并不深,现在开始从新开始学习编程。这里面的代码可能写的不是很规范,还请您指出,我会继续修改的。-->
言归正传,这次分享的Siri功能实际上提供的是一种智能助手,其作用是用户回复想了解的问题,可以是词语或者是句子,系统会自动回复所有可能的答案如图所示:
这个的先说一下这个功能现有的问题,只能匹配提问的语句中所有的名词词语,例如本例中提问的语句“学校怎么去火车站”,这句话中的名词有两个:“学校”,“火车站”所有就把有关这两个名词的答案全部列出。并不能像搜索引擎一样,“理解“这句话的含义,这个是我现在没有办法解决的。
下面开始分析设计思路。首先,这个功能的回复信息采用的“无图”的多条图文信息,官方提供的消息格式为
$textPicTpl = " <xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<Content><![CDATA[%s]]></Content>
<ArticleCount>1</ArticleCount>
<Articles>
<item>
<Title><![CDATA[%s]]></Title>
<Description><![CDATA[%s]]></Description>
<PicUrl><![CDATA[%s]]></PicUrl>
<Url><![CDATA[%s]]></Url>
</item>
</Articles>
<FuncFlag>0</FuncFlag>
</xml> ";
其中<ArticleCount>这个标签中的数值为图文信息的条数。如果不为1,那么只需要把<item></item>之间的代码重复即可,如果不想要图片,可以在回复的代码中把标签<PicUrl>中的变量置为空即可。由于微信官方提供的多条图文信息最多只支持10条信息。所以需要在回复信息格式的位置,事先把1-10的图文消息格式全部预制。
下一步便是整个功能的实现部分,先用一个流程图解释一下:
1.sae的分词功能:
sae中提供了这个服务官方给了一段demo如下:
<?php
$str = "明天星期天";
$seg = new SaeSegment();
$ret = $seg->segment($str, 1);
print_r($ret); //输出
// 失败时输出错误码和错误信息
if ($ret === false)
var_dump($seg->errno(), $seg->errmsg());
?>
上面实例中的分词结果为:
Array (
[0] => Array (
[word] => 明天
[word_tag] => 132
[index] => 0 )
[1] => Array (
[word] => 星期天
[word_tag] => 132
[index] => 1 )
)
其中word字段为分词后的词语,word_tag字段为词性代号(代号所表示的词性请见API:http://apidoc.sinaapp.com/sae/SaeSegment.html),index字段为编号。这里我们主要使用前两个字段。因为我还没有办法真正通过分词等技术实现彻底理解用户提问的意图,所以只好采用提取句子中的名词和一部分动词来作为可能的关键字,因为在通常情况下,名词和动词就是内容的关键。所以我们根据word_tag字段,分辨出所有的名词提取到数组$keywd_arr中,这个数组是一个一维数组,只存储了关键字。
2.数据库匹配关键字
我们需要预定义一个数据库,数据库结构为:SiriTable(id,title,keyword,content)其中id为主键,并且是自动编号,title用于显示在回复格式中的title,例如第一幅图中的“学校宿舍情况”“学校附近的商场”等标题文字。keyword用于存储这条记录可能的所有关键字,例如:title为“火车站公交路线”的keyword为“火车站”,“公交车”,"青岛站",这样,用户所输入的问题中凡是带有这3个关键字时,这条title为“火车站公交路线”的记录便会被取出。
通过自定义的方法,将第一个关键字与数据库匹配,取出匹配成功记录中的“title”“id”字段内容,因为一个关键字可能对应多条记录,所以结果存储到一个二维数组中,之后再用同样的方法匹配第二个关键字,将所有关键字匹配结束后,我们得到了很多个长度不同的二维数组,组成一个三维数组,这里为了输出方便,我做了一个调整,把这个三维数组转换为一个二维数组并输出。转换的原因,在后面提到。这里我先画一个示意图把上面的过程图示一下:
3.整合输出,这里需要处理的就是将所得到的信息以格式化的形式返回给用户,部分代码如下:
switch ($text_type_num) { //$text_type_num为返回的结果数量
case"0":
$msgType = "text";
$contentStr = "*琴院助手*
*未查到相关数据*
*将进行有道翻译*
" . language($keyword);
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
……
case"2": //查询结果为2条记录
$s_textPicTpl = $textPicTpl2;
$url = "http://1.testqdc.sinaapp.com/siri_pro.php?way=" . $kwd_re_arr[0][1]; //第一条记录的跳转地址,其中$kwd_re_arr[0][1]为第一条记录的id值,以get方式传递到显示页面
$url1 = "http://1.testqdc.sinaapp.com/siri_pro.php?way=" . $kwd_re_arr[1][1]; //第二条记录的跳转地址
$title = $kwd_re_arr[0][0]; //第一条记录标题
$title1 = $kwd_re_arr[1][0]; //第二条记录标题
$description = ""; //消息描述定义为空
$picurl = ""; //图片url定义为空
$resultStr = sprintf($s_textPicTpl, $fromUsername, $toUsername, $time, $msgType, $title, $description, $picurl, $url, $title1, $description, $picurl, $url1);
break;
……
}
上面是以返回2条记录为例说明。
之后就是跳转的显示页面了,很简单,直接看代码吧:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body bgcolor="#9dd6f4" text="#011126">
<style>
body{font-size:55px;text-align:center}
</style>
<?php
// put your code here
$id=$_GET["way"];
$con = mysql_connect(SAE_MYSQL_HOST_M.':'.SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS);
mysql_select_db("数据库名称", $con);
$sql1="select * from 数据表名称 where id=".$id;
$result11=mysql_query($sql1,$con);
$info= mysql_fetch_assoc($result11);
echo "<br><br>**琴院Siri助手**<br>".$info['content'];
mysql_close($con);
?>
</body>
</html>
以上就是这个功能的开发过程。