db.php
<?php
return new PDO("mysql:host=127.0.0.1;dbname=数据库名",'数据库用户名','密码',[
// 有错误抛异常
PDO::ERRMODE_EXCEPTION,
// 以关联数组的形式输出
PDO::FETCH_ASSOC
]);
被动.php
<?php
$wx = new Wx();
/**
* 微信被动模式
*/
class Wx
{
// 自定义token
private const TOKEN = 'xxx';
// 数据库对象
private $pdo;
// 构造方法
public function __construct()
{
// 是否第一次接入
if (!empty($_GET['echostr'])) {
echo $this->checkSigin();
} else {
$this->pdo = include './db.php';
$this->acceptMsg();
}
}
/**
* 接收公众号发过来的数据
*
*/
private function acceptMsg()
{
// 获取原生请求数据
$xml = file_get_contents('php://input');
$obj = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
// 写日志
$msgType = $obj['MsgType'];
// 判断类型处理
$fun = $msgType . 'Fun';
// 取消关注不写日志
if ($obj['Event'] != 'unsubscribe') {
$this->writeLog($xml);
}
echo $this->$fun($obj);
}
/**
* 写日志
* @param string $xml 写入xml
* @param int|integer $flag 标识 1:请求 2:发送
*
*/
private function writeLog(string $xml, int $flag = 1)
{
$flagStr = $flag == 1 ? '请求' : '发送';
$prevstr = '[' . $flagStr . ']' . date('Y-m-d') . "---------------\n";
$log = $prevstr . $xml . "\n---------------\n";
file_put_contents('wx.xml', $log, FILE_APPEND);
}
/**
* 发起请求
* @param string $url
* @param string|array $ret 请求体
*
*/
private function http_req($url, $ret = '')
{
// 初始化
$ch = curl_init();
// 相关设置
curl_setopt($ch, CURLOPT_URL, $url);
// 不要请求头
curl_setopt($ch, CURLOPT_HEADER, 0);
// 请求结果不直接输出,而是字符串返回
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
# 设置请求超时时间 s
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
# 设置浏览器型号
curl_setopt($ch, CURLOPT_HEADER, 'MSIE001');
# 证书不检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
# 设置为post请求
if ($ret != '') {
// 开启post
curl_setopt($ch, CURLOPT_POST, 1);
// post请求数据
curl_setopt($ch, CURLOPT_POSTFIELDS, $ret);
}
// 发起请求
$data = curl_exec($ch);
// 有无发送异常
if (curl_errno($ch) > 0) {
// 把错误发送给客户端
# echo curl_error($ch);
$data = '';
}
// 关闭请求
curl_close($ch);
return $data;
}
/**
* 处理回复文本
*
*/
private function textFun($obj)
{
// 回复文本
if ($obj['Content'] == '一串文本') {
return $this->audioFun($obj);
}elseif (strstr($obj['Content'],'位置-')){
// 客户端发送指定格式文本 服务端调用后返回
# 得到关键词
$kw = str_replace('位置-','',$obj['Content']);
$kw = trim($kw);
$url = 'http://api.map.baidu.com/place/v2/search?query='.$kw.'&location=39.915,116.404&radius=2000&output=json&ak=百度ak';
echo $url;
$json = $this->http_req($url);
# json转为数组
$arr = json_decode($json, true);
# 判断是否有搜索结果
if(count($arr['results'])<=0){
return $this->createText($obj,'没有找到相关服务');
}
var_dump($arr['results']);
$list = '';
foreach($arr['results'] as $value){
$list.=($value['name'])."\n";
}
return $this->createText($obj,$list);
}
$content = '公众号:' . $obj['Content'];
return $this->createText($obj, $content);
}
/**
* 语音处理
*/
private function voiceFun($obj)
{
$content = (string) $obj['Recognition'];
$content = ($content) ?? '无解';
echo $content;
return $this->createText($obj, $content);
}
/**
* 处理回复语音
*
*/
private function audioFun($obj)
{
// 回复语音
$url = 'http://ty.8zl.cn/file/754489012/91376212247374821/M500001QhFgK2RH3J7.mp3';
$mediaid = '_IiZWnxXTcApusLcp-zIFif5f96yePn4IAvHdbCXhF2DJWKApF9VA1Y_A5WxwG5Q';
return $this->createAudio($obj, $url, $mediaid);
}
/**
* 处理回复图片
*
*/
private function imageFun($obj)
{
$mediaid = $obj['MediaId'];
return $this->createImage($obj, $mediaid);
}
/**
*生成文本信息XML
*/
private function createText($obj, string $content)
{
$xml = '
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>
';
// 格式化替换输出
$str = sprintf($xml, $obj['FromUserName'], $obj['ToUserName'], time(), $content);
$this->writeLog($str, 2);
return $str;
}
/**
*生成图片信息XML
*/
private function createImage($obj, string $mediaid)
{
$xml = '
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[%s]]></MediaId>
</Image>
</xml>
';
// 格式化替换输出
$str = sprintf($xml, $obj['FromUserName'], $obj['ToUserName'], time(), $mediaid);
$this->writeLog($str, 2);
return $str;
}
/**
*生成语音信息XML
*/
private function createAudio($obj, string $url = '', string $mediaid = '')
{
$xml = '
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[music]]></MsgType>
<Music>
<Title><![CDATA[xxxx]]></Title>
<Description><![CDATA[无]]></Description>
<MusicUrl><![CDATA[%s]]]></MusicUrl>
<HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl>
<ThumbMediaId><![CDATA[%s]]></ThumbMediaId>
</Music>
</xml>';
// 格式化替换输出
$str = sprintf($xml, $obj['FromUserName'], $obj['ToUserName'], time(), $url, $mediaid);
return $str;
}
/**
* 初次接入 检验
*/
private function checkSigin()
{
$input = $_GET;
$echostr = $input['echostr'];
$signature = $input['signature'];
// 数组清除 放临时变量
unset($input['echostr'], $input['signature']);
// 数据中添加字段token
$input['token'] = self::TOKEN;
// 字典排序
$tmpStr = implode($input);
// 加密
$tmpStr = sha1($tmpStr);
// 比对
if ($tmpStr === $signature) {
return $echostr;
}
return '';
}
/**
* 按钮点击事件
*/
private function clickFun($obj)
{
$EventKey = $obj['EventKey'];
if ('index001' == $EventKey) {
return $this->createText($obj, '你点击首页按钮');
} elseif ('kefu001' == $EventKey) {
return $this->createText($obj, '你点击客服按钮');
}
return $this->createText($obj, '无法解决!');
}
/**
* 事件处理
*/
private function eventFun($obj)
{
// 事件名称
$Event = $obj['Event'];
switch ($Event) {
case 'CLICK':
// 关于点击事件
return $this->clickFun($obj);
break;
case 'LOCATION':
// 关于点击事件
$longitude = $obj['Longitude'];
$latitude = $obj['Latitude'];
$openid = $obj['FromUserName'];
// 修改表记录
$sql = "update fx set longitude=?,latitude=? where openid=?";
$stmt = $this->pdo->prepare($sql);
$stmt->execute([$longitude, $latitude, $openid]);
break;
case 'subscribe':
// 如果evnetkey 无值 表示顶级
$EventKey = ($obj['EventKey']);
if (empty($EventKey)) {
// 首次关注添加数据库
$sql = "insert into fx (openid) values (?)";
$stmt = $this->pdo->prepare($sql);
$stmt->execute([$obj['FromUserName']]);
} else {
# 得到上级id号
$id = (int) str_replace('qrscene_', '', $EventKey);
# 查询记录
$sql = "select * from fx where id=$id";
$row = $this->pdo->query($sql)->fetch();
# 添加本人记录到数据库
$sql = "insert into fx (openid,f1,f2,f3) values(?,?,?,?)";
$stmt = $this->pdo->prepare($sql);
$openid = $obj['FromUserName'];
$stmt->execute([$openid, $row['openid'], $row['f1'], $row['f2']]);
}
return $this->createText($obj, "欢迎关注公众平台\n哈哈");
break;
}
}
}