微信公众号的程序接入 - PHP 版本源代码

简介: 微信公众号的程序接入 - PHP 版本源代码


  1. Create a PHP project by referring to the following source code:
<?php
use sinacloud\sae\Storage as Storage; //upload mp3 to sina cloud
// define your token
define ( "TOKEN", "jerry" );
define ("BAIDU_TOKEN","24.229b04dcbe1338b22051faf6d8f5c3ef.2592000.1459386754.282335-7707083");
$wechatObj = new Weichat_base_api ();
if (isset ( $_GET ['echostr'] )) {
  $wechatObj->valid (); // 验证URL有效性,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。
} else {
  $wechatObj->responseMsg ();
}
class Weichat_base_api {
  public function valid() {
    $echoStr = $_GET ["echostr"];
    if ($this->checkSignature ()) {
      echo $echoStr;
      exit ();
    }
  }
  private function checkSignature() // 配置时验证URL有效性
  {
    // you must define TOKEN by yourself
    if (! defined ( "TOKEN" )) {
      throw new Exception ( 'TOKEN is not defined!' );
    }
    
    $signature = $_GET ["signature"]; // 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
    $timestamp = $_GET ["timestamp"]; // 时间戳
    $nonce = $_GET ["nonce"]; // 随机数
    
    $token = TOKEN;
    $tmpArr = array (
        $token,
        $timestamp,
        $nonce 
    );
    // use SORT_STRING rule
    sort ( $tmpArr, SORT_STRING );
    $tmpStr = implode ( $tmpArr );
    $tmpStr = sha1 ( $tmpStr );
    
    if ($tmpStr == $signature) {
      return true;
    } else {
      return false;
    }
  }
  
  public function responseMsg() {
    $postStr = $GLOBALS ["HTTP_RAW_POST_DATA"];
    
    if (! empty ( $postStr )) {
      $postObj = simplexml_load_string ( $postStr, 'SimpleXMLElement', LIBXML_NOCDATA );
      $fromUsername = $postObj->FromUserName;
      $toUsername = $postObj->ToUserName;
      $time = time ();
      switch ($postObj->MsgType) {
        case "text" :
          echo $this->receiveText($postObj);
          break;
        case "image" :
          echo $this->receiveImg($postObj);
          break;
        case "voice" :
          echo $this->receiveVoice($postObj);
          break;
        case "shortvideo" :
          $newsArr = array(
            array(
              "Title"=>"周哥测试1",
              "Description"=>"这是周哥测试的描述信息",
              "PicUrl"=>"https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=2026430319,4041659&fm=80",
              "Url"=>"http://news.163.com/16/0113/08/BD6RQDT500011229.html",
            ),
            array(
              "Title"=>"周哥测试2",
              "Description"=>"这是周哥测试的描述信息 II",
              "PicUrl"=>"https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=3624483189,4086732657&fm=80",
              "Url"=>"http://cnews.chinadaily.com.cn/2016-01/13/content_23061286.htm",
            ),
          );
          echo $this->replyNews($postObj,$newsArr);
          break;
        case "video" :
          echo $this->receiveVideo($postObj);
          break;
        case "location" :
          echo $this->receiveLocation($postObj);
          break;
        case "link" :
          echo $this->receiveLink($postObj);
          break;
        case "event":
          $this->receiveEvent($postObj);
          break;
      }
       
    } else {
      echo "";
      exit ();
    }
  }
  private function receiveText($obj)
  {
    $content = $obj->Content;
    return $this->tuling_api($obj,$content);
  }
  
  private function receiveImg($obj)
  {
    //获取图片消息的内容
    $imageArr = array(
        "PicUrl"=>$obj->PicUrl,
        "MediaId"=>$obj->MediaId
        );
    return $this->replyimg($obj, $imageArr);
  }
  private function receiveLocation($obj){
    $locationArr = array(
        "Location_X"=>$obj->Location_X,
        "Location_Y"=>$obj->Location_Y,
        "Label"=>$obj->Label
    );
    return $this->replyLocation($obj, $locationArr);
  }
  
  private function receiveVoice($obj){
    if(isset($obj->Recognition))
    {
      $voice_content = $obj->Recognition;
      return $this->tuling_api($obj,$voice_content,"voice");
    }
    else
    {
      $voiceArr = array(
          "MediaId"=>$obj->MediaId,
          "Format"=>$obj->Format
      );
      return $this->replyVoice($obj, $voiceArr);
    }
  }
  private function receiveVideo($obj){
    $videoArr = array(
        "MediaId"=>$obj->MediaId,
        "ThumbMediaId"=>$obj->ThumbMediaId,
        "MsgId"=>$obj->MsgId
    );
    return $this->replyVideo($obj, $videoArr);
  }
  private function receiveLink($obj){
    $linkArr = array(
        "Title"=>$obj->Title,
        "Description"=>$obj->Description,
        "Url"=>$obj->Url
    );
    return $this->replyLink($obj, $linkArr);
  }
  
  private function receiveEvent($obj){
    switch ($obj->Event){
      case "subscribe":
        if(!empty($obj->EventKey)){
          //通过扫描带参数的二维码进行关注的逻辑
    
        }
        echo $this->replyText($obj,"你好,欢迎你关注我们的微信公众号码,给我们发送语音,调戏一下客服机器人吧,您可以说【成都天气】或者【明天从北京飞上海的航班】等!");
        break;
      case "unsubscribe":
        //write to data base about the unsubscribe
        break;
      case "SCAN":
        //已关注的情况下扫描带参数的二给码的逻辑
        break;
      case "LOCATION":
        break;
      case "CLICK":
        switch ($obj->EventKey){
          case "V1001_TODAY_MUSIC":
            echo $this->replyText($obj, "您点击的是[关于我们]");
            break;
          default:
            echo $this->replyText($obj, "谢谢您 的打赏!");
            break;
        }
        break;
    }
  }
  
  private function replyText($obj, $content)
  {
    $textTpl = "<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[text]]></MsgType>
                        <Content><![CDATA[%s]]></Content>
                        <FuncFlag>0</FuncFlag>
                        </xml>";
    
    $resultStr = sprintf ( $textTpl, $obj->FromUserName, $obj->ToUserName, time(), $content );
    return $resultStr;
  }
  
  private function replyImg($obj, $imageArr){
    $replyXml = "<xml>
            <ToUserName><![CDATA[%s]]></ToUserName>
            <FromUserName><![CDATA[%s]]></FromUserName>
            <CreateTime>%s</CreateTime>
            <MsgType><![CDATA[image]]></MsgType>
            <Image>
            <MediaId><![CDATA[%s]]></MediaId>
            </Image>
          </xml>";
    return sprintf ( $replyXml, $obj->FromUserName, $obj->ToUserName, time(), $imageArr['MediaId'] );
  }
  private function replyLocation($obj, $locationArr){
    return $this->replyText($obj, $locationArr['Label']);
  }
  private function replyVoice($obj, $voiceArr){
    $replyXml = "<xml>
          <ToUserName><![CDATA[%s]]></ToUserName>
          <FromUserName><![CDATA[%s]]></FromUserName>
          <CreateTime>%s</CreateTime>
          <MsgType><![CDATA[voice]]></MsgType>
          <Voice>
          <MediaId><![CDATA[%s]]></MediaId>
          </Voice>
          </xml>";
    return sprintf ( $replyXml, $obj->FromUserName, $obj->ToUserName, time(), $voiceArr['MediaId'] );
  }
  private function replyVideo($obj, $videoArr){
    $replyXml = "<xml>
          <ToUserName><![CDATA[%s]]></ToUserName>
          <FromUserName><![CDATA[%s]]></FromUserName>
          <CreateTime>%s</CreateTime>
          <MsgType><![CDATA[video]]></MsgType>
          <Video>
          <MediaId><![CDATA[%s]]></MediaId>
          <Title><![CDATA[%s]]></Title>
          <Description><![CDATA[%s]]></Description>
          </Video> 
          </xml>";
    return sprintf ( $replyXml, $obj->FromUserName, $obj->ToUserName, time(), $videoArr['MediaId'], "这是视频标题", "这是视频具体的描述信息!" );   
  }
  private function replyMusic($obj, $musicArr){
    $replyXml = "<xml>
          <ToUserName><![CDATA[%s]]></ToUserName>
          <FromUserName><![CDATA[%s]]></FromUserName>
          <CreateTime>%s</CreateTime>
          <MsgType><![CDATA[music]]></MsgType>
          <Music>
          <Title><![CDATA[%s]]></Title>
          <Description><![CDATA[%s]]></Description>
          <MusicUrl><![CDATA[%s]]></MusicUrl>
          <HQMusicUrl><![CDATA[%s]]></HQMusicUrl>
          </Music>
          </xml>";
    return sprintf($replyXml,$obj->FromUserName,$obj->ToUserName,time(),$musicArr['Title'],$musicArr['Description'],$musicArr['MusicURL'],$musicArr['HQMusicUrl']);
  }
  private function replyLink($obj, $linkArr){
    return $this->replyText($obj, $linkArr['Description']);
  }
  private function replyNews($obj, $newsArr){
    $itemXml = "";
    if(is_array($newsArr))
    {
      foreach($newsArr as $item)
      {
        $itemStr = "<item>
              <Title><![CDATA[%s]]></Title>
              <Description><![CDATA[%s]]></Description>
              <PicUrl><![CDATA[%s]]></PicUrl>
              <Url><![CDATA[%s]]></Url>
              </item>";
        $itemXml .= sprintf ( $itemStr, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);
      }
    }
    
    $replyXml = "<xml>
          <ToUserName><![CDATA[%s]]></ToUserName>
          <FromUserName><![CDATA[%s]]></FromUserName>
          <CreateTime>%s</CreateTime>
          <MsgType><![CDATA[news]]></MsgType>
          <ArticleCount>%s</ArticleCount>
          <Articles>
          {$itemXml}
          </Articles>
          </xml>";
    return sprintf ( $replyXml, $obj->FromUserName, $obj->ToUserName, time(),count($newsArr));
  }
  private function https_request($url,$data=null)
  {
    $ch = curl_init();
    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
    if($data)
    {
      curl_setopt($ch,CURLOPT_POST,1);//模拟Post
      curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }
    $outopt = curl_exec($ch);
    curl_close($ch);
    $outoptArr = json_decode($outopt,true);
    if(is_array($outoptArr))
    {
      return $outoptArr;
    }
    else
    {
      return $outopt;
    }
  }
  private function get_baidu_voice($content)
  {
    $content=urlencode($content);
    $baidu_token=BAIDU_TOKEN;
    $baidu_voice_url="http://tsn.baidu.com/text2audio?tex={$content}&lan=zh&cuid=CTU50915170&ctp=1&tok={$baidu_token}";
    $voice=$this->https_request($baidu_voice_url);
    return $voice;
  }
  private function upload_media($content)
  {
  
    //Upload media to Sina Cloud to get access url
    $storage=new Storage();
    $mediaName=time().".mp3";
    $bucketName="mp3";
    $storage->putObject($content,$bucketName,$mediaName);
    $mp3Url=$storage->getUrl($bucketName,$mediaName);
    return $mp3Url;
    //currently not able to upload a network mp3 to weichat server
    /*
      $access_token=$this->get_access_token();
      $url="https://api.weixin.qq.com/cgi-bin/media/upload?access_token={$access_token}&type=voice";
      //file_put_contents("123.mp3","http://tsn.baidu.com/text2audio?tex=%E8%BF%99%E6%98%AF%E6%88%91%E6%83%B3%E8%A6%81%E8%AE%A9%E4%BD%A0%E8%AF%BB%E5%87%BA%E6%9D%A5%E7%9A%84%E8%AF%AD%E9%9F%B3%E4%BF%A1%E6%81%AF%EF%BC%8C%E4%BD%A0%E8%A7%89%E5%BE%97%E6%88%91%E8%AF%BB%E5%BE%97%E6%80%8E%E4%B9%88%E6%A0%B7%EF%BC%9F&lan=zh&cuid=CTU50915170&ctp=1&tok=24.4abf9d281640a29052eed0a77908d445.2592000.1456367301.282335-7707083");
      $post=array("filename"=>"@http://bille001-mp3.stor.sinaapp.com/1454081891.mp3");
      $mediaArr=$this->https_request($url,$post);
      return $mediaArr;*/
  }
  private function tuling_api($obj,$question,$type="text")
  {
    $question_en=urlencode($question);
    $tulingURL = "http://www.tuling123.com/openapi/api?key=de4ae9269c7438c33de5806562a35cac&info={$question_en}";
    $tulingResultArr=$this->https_request($tulingURL);
    if(isset($tulingResultArr['url']))
    {
      return $this->replyText($obj,$tulingResultArr['text']." ".$tulingResultArr['url']);
    }
    elseif(isset($tulingResultArr['list']))
    {
      $listArr = $tulingResultArr['list'];
      $itemObj = new ArrayObject();
      $i = 0;
      foreach($listArr as $list)
      {
        if(!empty($list['article']))
        {
          $description = $list['source'];// news
          $title = $list['article'];
        }
        else
        {
          $description = $list['info']; // cookbook
          $title = $list['name'];
        }
        $item = array(
            "Title"=>$title,
            "Description"=>$description,
            "PicUrl"=>$list['icon'],
            "Url"=>$list['detailurl'],
        );
        $i++;
        if ($i<10)
        {
          $itemObj->append($item);
        }
  
      }
      $itemArr = $itemObj->getArrayCopy();
      return $this->replyNews($obj,$itemArr);
    }
    else
    {
      if($type=="text")
      {
        return $this->replyText($obj,$tulingResultArr['text']);
      }
      else
      {
        $baidu_content = $this->get_baidu_voice($tulingResultArr['text']);
        $mp3Url=$this->upload_media($baidu_content);
        $musicArr=array(
            "Title"=>"Q:".$question,
            "Description"=>"A:".$tulingResultArr['text'],
            "MusicURL"=>$mp3Url,
            "HQMusicUrl"=>$mp3Url,
        );
        return $this->replyMusic($obj,$musicArr);
      }
        
    }
  }
}
?>
  1. Once done, deploy it to Heroku:

Click Open App button to get the application url:

  1. Configure the url to your public Wechat account:


相关文章
|
20天前
|
Java API PHP
【亲测有效,官方提供】php版本企查查api接口请求示例代码,php请求企查查api接口,thinkphp请求企查查api接口
【亲测有效,官方提供】php版本企查查api接口请求示例代码,php请求企查查api接口,thinkphp请求企查查api接口
35 1
|
25天前
|
PHP 开发工具
php免费用免认证的微信支付宝支付
php免费用免认证的微信支付宝支付
18 5
|
25天前
|
PHP
php使用curl新增微信临时素材(上传图片)
php使用curl新增微信临时素材(上传图片)
76 4
|
26天前
|
API
个人微信api接口源代码
个人微信api接口源代码
|
1月前
|
PHP
PHP微信公众号投票活动系统源码
PHP微信公众号投票活动系统源码
122 11
|
1月前
|
XML JSON 数据安全/隐私保护
如何使用Fiddler抓取APP接口和微信授权网页源代码
Fiddler是一款强大的抓包工具,用于捕获HTTP/HTTPS流量,包括手机APP和微信授权页面的数据。下载安装Fiddler后,需设置电脑代理,如端口8888,并在手机上配置相同代理,确保两者在同一局域网。通过安装Fiddler证书,可解密HTTPS请求。在手机上打开目标应用或网页,Fiddler将显示请求详情,便于接口调试和数据查看。
45 0
如何使用Fiddler抓取APP接口和微信授权网页源代码
|
20天前
|
移动开发 小程序 前端开发
php + h5使用 scheme页面跳转微信小程序-其他浏览器一键跳转到微信并打开小程序
php + h5使用 scheme页面跳转微信小程序-其他浏览器一键跳转到微信并打开小程序
14 0
|
20天前
|
缓存 前端开发 PHP
【超详细】php实现扫码关注微信公众号系统/网站自动注册登录
【超详细】php实现扫码关注微信公众号系统/网站自动注册登录
21 0
|
1月前
|
PHP 移动开发 安全
PHP应用如何对接微信公众号JSAPI支付
本文介绍了微信支付的多种方式,包括JSAPI支付、APP支付、Native支付、付款码支付和H5支付。
28 8
|
2月前
|
PHP
PHP公众号开发给用户发微信消息提醒功能
该内容是一个关于如何在时间紧迫的情况下,通过微信客服消息接口实现用户资金到账或成员变动时发送微信通知的项目总结。
33 2