php调用心知天气API,实现微信自动回复

一:

1.定义一个专门用于发送api请求和处理api接收数据的类

2.类中定义两个方法:1个用于生成连接api所用的url,一个用于连接api并且处理返回数据

3. 请求地址:https://api.seniverse.com/v3/weather/now.json

4.阅读心知天气api文档心知天气api示例代码(php)

5.容易出问题的地方:

     1)在连接api和处理消息方法中,用cURL进行连接,tips:curl连接的时候不要使用服务器验证!!!,不设置hedding,不设置host,否则连接不了api,正确示范如官方提供的demo参考。

      2)api返回的是json格式,用php提供的json转数组函数可以转数组,这个数组是一个多维的数组,注意取值的时候不要出错,数组为索引数组+关联数组混合,如下面代码所示

$output['results'][0]['location']['name']

这里取到的就是城市名字。

6.整体思路:在回复文本消息方法中调用生成URL链接函数,将用户发送的城市名字传过来;URL链接函数调用连接方法,在连接方法中返回处理完成的字符串,可供被动回复文本消息方法直接回复。

7.实例code demo :wether.php

<?php
/*调用心知天气api demo
*/
//自动转数组并返回查询结果字符串
class wetherReplay
{
    function httpGet($url)
    {
        $ch = curl_init();//c初始化一个cURL会话
        curl_setopt($ch, CURLOPT_URL, $url);//将URL设置为我们需要的URL
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        $output = curl_exec($ch);//获取json返回数据
        curl_close($ch);
        $output = json_decode($output, true);//将获取到的json转化成php数组
        $retStr = "您查询的城市:" .$output['results'][0]['location']['name'] . "\n" . "今日天气:" .$output['results'][0]['now']['text']
            . "\n" . "温度:" .$output['results'][0]['now']['temperature'] ."摄氏度";
        return $retStr;
    }
// 心知天气接口调用凭据
public function wetherCallBackTest($pos)
{
    $key = '6wd17nam8wcitv0f'; // 测试用 key,请更换成您自己的 Key
    $uid = 'U270B81E1D'; // 测试用 用户 ID,请更换成您自己的用户 ID
// 参数
    $api = 'https://api.seniverse.com/v3/weather/now.json'; // 接口地址
    $location = $pos; // 城市名称。除拼音外,还可以使用 v3 id、汉语等形式
// 生成签名。文档:https://www.seniverse.com/doc#sign
    $param = [
        'ts' => time(),
        'ttl' => 300,
        'uid' => $uid,
        ];
    $sig_data = http_build_query($param); // http_build_query 会自动进行 url 编码
// 使用 HMAC-SHA1 方式,以 API 密钥(key)对上一步生成的参数字符串(raw)进行加密,然后 base64 编码
    $sig = base64_encode(hash_hmac('sha1', $sig_data, $key, TRUE));
// 拼接 url 中的 get 参数。文档:https://www.seniverse.com/doc#daily
    $param['sig'] = $sig; // 签名
    $param['location'] = $location;
    $param['start'] = 0; // 开始日期。0 = 今天天气
    $param['days'] = 1; // 查询天数,1 = 只查一天
// 构造 url
    $url = $api . '?' . http_build_query($param);
    return $this->httpGet($url);
}
}

 

二:被动回复消息类:

1.在文本消息中分辨出用户是否发送询问天气消息,自定义判断规则 eg:用户发送南阳天气时,strstr()识别出字符串是否有天气两字,若有,进入到回复天气模块,没有,正常进入回复模块;

2.城市名字是不一定两个字的,所以使用mb_strlen()来判断用户输入的字符个数,然后减去2就是城市名字的字符个数,再使用mb_substr()来截取这个字符长度的城市名字

3.code demo  replay.php

<?php
require 'wether.php';//包含文件,以使可以调用该文件的方法
//$wetherReplay = new wetherReplay();
//回复消息类
class ReplyMsageUntion{
//回复消息选择器
    public function messageSwitch()
    {
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];

        if (!empty($postStr)) {
            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);

            switch ($postObj->MsgType) {
                case 'text':
                    $this->replayText($postObj);
                    break;
                case  'image':
                    $this->replayImage($postObj);
                    break;
                case 'voice':
                    $this->replayAudio($postObj);
                case 'video';
                    $this->replayVideo($postObj);
            }
        }else
            echo "";
    }
    //文本消息回复函数
    private function replayText($postObj)
    {
        $wetherReplay = new wetherReplay();//new一个对象才可以调用生成URL方法
        $fromUser = $postObj->FromUserName;
        $toUser = $postObj->ToUserName;
        $mType = $postObj->MsgType;
        $keyWord = trim($postObj->Content);
        $time = date("Y:m:d H:i:s", time());

        //如果消息中包含天气,则回复天气预报
        if(strstr($keyWord,"天气")){//strstr()用来检测是否有固定字符串出现
            $lenthContent = mb_strlen($keyWord,'utf-8');//判断用户输入的字符串长度
            $pos = mb_substr($keyWord,0,$lenthContent-2,'utf-8');//截取城市名字
            $wetherRet = $wetherReplay->wetherCallBackTest($pos);//调用天气生成URL方法

            $textStr = "<xml>
                <ToUserName><![CDATA[%s]]></ToUserName> 
                <FromUserName><![CDATA[%s]]></FromUserName> 
                <CreateTime>%s</CreateTime> 
                <MsgType><![CDATA[%s]]></MsgType> 
                <Content><![CDATA[%s]]></Content>
                <FuncFlag>0</FuncFlag>
            </xml>";
            $resultStr = sprintf($textStr,$fromUser,$toUser, $time, $mType,$wetherRet);
            echo $resultStr;
        }else{
 //       $time = date("Y:m:d H:i:s", time());

            $textStr = "<xml>
                <ToUserName><![CDATA[%s]]></ToUserName> 
                <FromUserName><![CDATA[%s]]></FromUserName> 
                <CreateTime>%s</CreateTime> 
                <MsgType><![CDATA[%s]]></MsgType> 
                <Content><![CDATA[%s]]></Content>
                <FuncFlag>0</FuncFlag>
            </xml>";
            // if (!empty($keyWord)){
            $contentStr = "已收到您的消息:".$postObj->Content ."\n" ."发送时间" .$time;
            $resultStr = sprintf($textStr,$fromUser,$toUser, $time, $mType,$contentStr);
            echo $resultStr;
        }
    }
     //图片消息回复函数
    private function replayImage($postObj){
        $fromUser = $postObj->FromUserName;
        $toUser = $postObj->ToUserName;
        $mType = $postObj->MsgType;

        $time = date("Y:m:d H:i:s", time());
        $imageStr = "<xml>
            <ToUserName><![CDATA[%s]]></ToUserName>
            <FromUserName><![CDATA[%s]]></FromUserName>
            <CreateTime>%s</CreateTime>
            <MsgType><![CDATA[%s]]></MsgType>
            <Image>
                <MediaId><![CDATA[%s]]></MediaId>
            </Image>
            </xml>";
      //  $contentStr = "您发送的是一张图片,点击以下链接查看:"."\n" .$postObj->MediaId;
        $resultStr = sprintf($imageStr,$fromUser,$toUser,$time,$mType,$postObj->MediaId);
        echo $resultStr;
    }
    //回复语音消息
    private function replayAudio($postObj){
        $fromUser = $postObj->FromUserName;
        $toUser = $postObj->ToUserName;
        $mType = $postObj->MsgType;
        $time = date("Y:m:d H:i:s", time());

        $audeoStr = "<xml>
            <ToUserName><![CDATA[%s]]></ToUserName>
            <FromUserName><![CDATA[%s]]></FromUserName>
            <CreateTime>%s</CreateTime>
            <MsgType><![CDATA[%s]]></MsgType>
            <Voice>
                <MediaId><![CDATA[%s]]></MediaId>
            </Voice>
        </xml>";
        $resultStr = sprintf($audeoStr,$fromUser,$toUser,$time,$mType,$postObj->MediaId);
        echo $resultStr;
    }
    //回复视频消息
    private function replayVideo(){
        $fromUser = $postObj->FromUserName;
        $toUser = $postObj->ToUserName;
        $mType = $postObj->MsgType;
        $time = time();

        $videoStr = "<xml>
            <ToUserName><![CDATA[%s]]></ToUserName>
            <FromUserName><![CDATA[%s]]></FromUserName>
            <CreateTime>%s</CreateTime>
            <MsgType><![CDATA[%s]]></MsgType>
            <Video>
                <MediaId><![CDATA[%s]]></MediaId>
            //    <Title><![CDATA[%s]]></Title>
            //    <Description><![CDATA[%s]]></Description>
            </Video>
            </xml>";

         //   $contentTitle = "视频消息";
         //   $contentDesc = "点击即可观看";
            $resultStr = sprintf($videoStr,$fromUser,$toUser,$time,$mType,$postObj->MediaId);
            echo $resultStr;
    }
}

三 入口文件

1.服务器绑定校验签名 tips:签名不用每次请求都绑定,所以要加一个判断条件

2.code demo  api.php

<?php
require 'replay.php';
define("TOKEN","flyingman");
$wechatObj = new wechatCallBackTest();
$replayMseeg = new ReplyMsageUntion();
    if (!(isset($_GET["echostr"]))){
    $replayMseeg->messageSwitch();
    }else{
    $wechatObj->valid();
    }

class wechatCallBackTest{

//校验签名
        public function valid()
        {
            $signature = $_GET["signature"];//微信返回的加密字符串
            $timestamp = $_GET["timestamp"];
            $nonce = $_GET["nonce"];

            $token = TOKEN;
            $tmpArr = array($token, $timestamp, $nonce);
            sort($tmpArr, SORT_STRING);
            $tmpStr = implode($tmpArr);
            $tmpStr = sha1($tmpStr);

            if ($tmpStr == $signature) {
                echo $_GET["echostr"];
            }
        }
    }


四 总结

1.以上code可以实现微信被动回复文本,语音,图片,天气查询

2. 天气查询限定格式:城市名+天气

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值