ホームページ  >  記事  >  バックエンド開発  >  PHP に基づいた WeChat 開発用のパラメーターを含む QR コードの使用を実装する

PHP に基づいた WeChat 開発用のパラメーターを含む QR コードの使用を実装する

墨辰丷
墨辰丷オリジナル
2018-06-01 15:53:152218ブラウズ

この記事では主にPHP WeChat開発におけるパラメータ付きQRコードの使用方法を詳しく紹介しますので、興味のある方は参考にしてみてください

最近、初心者の観点から、PC Webページ用のWeChat関連機能を開発しています。 WeChat のパブリック アカウントのドキュメントは依然として理解しにくいです。オンラインで見つかる投稿のほとんどは、基本的に WeChat のパブリック プラットフォームで提供されるドキュメントのコピーです。WeChat のパラメータ化された QR コードを開発する過程では、依然として多くの落とし穴が存在します。私の開発プロセスをここに詳しく記録します。皆さんのお役に立てれば幸いです。

この開発には認証サービスアカウントを使用しています。

1 アクセス
まずWeChat公式アカウントを入力します -> 基本設定
以下は、私が使用するWeChatプッシュイベントを受け入れるためのインターフェースです。 thinkPHP フレームワーク 開発したプログラムの場合、いずれかのモジュール (装飾) のアクション ディレクトリに新しいクラスを作成します (例: WechatAction.class.php)。アクションに新しいパブリック メソッドを作成します (例: URLRedirect())。次に、URL を入力します。その 1 つは
http://[IP]:[port]/index.php/Decoration/Wechat/UrlRedirect です。次に、トークンを入力します。好きなようにトークンを入力します。EncodingAESKey またはそうでない場合は、[確認] をクリックすると、WeChat はこの URL に get リクエストを送信します。これには多くのパラメーターが含まれており、WeChat サーバーによってアクセスが要求されているかどうかを確認できます。チェックが成功すると get リクエストがそのまま返されます。ここでの戻り値は return でも ajaxReturn でもありませんが、thinkPHP を使用して開発する場合は、echo I('echostr' を使用してください。 ); 直接。その後、インターフェイスの検証は成功します。

2 パラメータ付きQRコードの役割
WeChatにはパラメータ付きQRコードの2種類があり、1つは一時的なQRコード、もう1つは永続的なQRコードですが、永続的なQRコードには制限があります今回実装したい機能は、ある商品の詳しい見積りが欲しいけど登録したくないけどログインせずにWebサイト上の商品を利用できる機能です。この時点で、ユーザーが WeChat で QR コードをスキャンする限り、Web ページはグラフィック メッセージをユーザーに送信します。をクリックすると、ユーザーが取得したばかりの見積書が表示されます。クリックするといつでも見積書を表示でき、価格比較のために友人と共有できます。したがって、一時的な QR コードは正常に使用できます。
上記は私がそれを使用する方法です。ここで対話プロセス全体を紹介します
:
ユーザーがこの QR コードをスキャンすると、ユーザーが公式アカウントをフォローしている場合、ユーザーは公式との会話ページに直接入ります。アカウント、WeChat サーバー メッセージは、前の手順で設定したサーバー URL にプッシュされます。これにはカスタム パラメーターを含めることができます。ユーザーが公式アカウントをフォローしていない場合、ユーザーはまず公式アカウントのフォローページに移動し、クリックすると公式アカウントの会話ページに直接アクセスします。パラメータをカスタマイズして、設定した URL にイベント メッセージをプッシュします。このパラメータとイベント タイプに基づいて次のアクションを制御できます。


3 具体的な開発プロセス


3.1 access_tokenを取得する
このaccess_tokenは、プログラムがWeChatインターフェースを呼び出すための証明書です。現在の有効期間は7200秒なので、定期的にaccess_tokenを更新する必要があります。 。
取得メソッド:

メソッド:
GETurl: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
パラメータAPPIDとAPPSECRETはパブリックですアカウントの APPID と APPSECRET は、WeChat 公式アカウント -> 基本設定で確認できます。呼び出しが成功すると、次の JSON データが返されます:
{"access_token":"ACCESS_TOKEN","expires_in":7200}

ここで、access_token は呼び出し側インターフェイスの資格情報、expire_in はトークンの有効期間です。

私は個人的に access_token をデータベースに保存し、有効期限を保存してから、パブリック関数 getWechatAccessToken() をカプセル化します。有効期限が切れている場合は、再度取得します。データベースに保存されている access_token を使用します。この access_token は 1 日に取得できる回数に制限があるとどこかで読んだのを忘れていました。 getWechatAccessToken() の具体的な実装は次のとおりです:


//获取access_token
function getWechatAccessToken(){
 $wechatInfo = M('wechat_info')->select();
 $wechatInfo = array_reduce($wechatInfo, create_function('$result, $v', '$result[$v["conf_name"]] = $v;return $result;'));
 $expireTime = $wechatInfo['PUBLIC_WECHAT_ACCESSTOKEN_EXPIRES']['conf_value'];        //前面不用管,是我数据库相应设置

 if (time() < $expireTime){    //access_token未过期
  return $wechatInfo[&#39;PUBLIC_WECHAT_ACCESSTOKEN&#39;][&#39;conf_value&#39;];
 }else{         //access_token过期,重新获取
  $baseUrl = C(&#39;WECHAT_PUBLIC_GET_ACCESS_TOKEN&#39;);
  $url = str_replace("##APPSECRET##", $wechatInfo[&#39;PUBLIC_WECHAT_APPSECRET&#39;][&#39;conf_value&#39;], str_replace("##APPID##", $wechatInfo[&#39;PUBLIC_WECHAT_APPID&#39;][&#39;conf_value&#39;], $baseUrl));
  $result = file_get_contents($url);
  $result = json_decode($result, true);

  if (array_key_exists(&#39;errorcode&#39;, $result)){  //失败重试一次
   return false;
  }else{
   M(&#39;wechat_info&#39;)->where(array(&#39;conf_name&#39; => &#39;PUBLIC_WECHAT_ACCESSTOKEN&#39;))->save(array(&#39;conf_value&#39; => $result[&#39;access_token&#39;]));
   M(&#39;wechat_info&#39;)->where(array(&#39;conf_name&#39; => &#39;PUBLIC_WECHAT_ACCESSTOKEN_EXPIRES&#39;))->save(array(&#39;conf_value&#39; => time()+$result[&#39;expires_in&#39;]-200));
   return $result[&#39;access_token&#39;];
  }
 }
}

C('WECHAT_PUBLIC_GET_ACCESS_TOKEN') =

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret= APPSECRET


これを梱包したら、いつでも安心して使用できます。

.2 一時的な QR コードを作成します

3.2.1 获取ticket3

请求方式: POST
接口:https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN
POST数据: {"expire_seconds": 604800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 123}}}
接口URL中的TOKEN即我们在3.1中获取的access_token,post数据中expire_seconds是二维码的有效时间,最多为30天,action_name临时二维码的话固定就是QR_SCENE,scene_id即我们自定义参数,是个32位非0整数,我在应用中把它设为订单的ID,微信服务器推送事件的时候会把这个值返回给我们设置的接口中,然后我会根据这个值去拿相应的订单数据展示在网页上,这是后话。 

下面是封装的生成临时二维码的方法: 

//创建临时二维码
function getTemporaryQrcode($orderId){
 $accessToken = getWechatAccessToken();
 $url = str_replace("##TOKEN##", $accessToken, C(&#39;WECHAT_PUBLIC_GET_TEMPORARY_TICKET&#39;));
 $qrcode = &#39;{"expire_seconds": 1800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": &#39;.$orderId.&#39;}}}&#39;;
 $result = api_notice_increment($url, $qrcode);
 $result = json_decode($result, true);
 return urldecode($result[&#39;url&#39;]);
}

其中的方法 api_notice_increment() 是我封装的一个POST方法函数,我试过很多POST的方法,可能由于微信接口对POST方法和参数的限制比较严格,这个浪费了好久时间,最后在网上找到了一个可以使用的封装好的POST方法,建议大家先自己试试,如果微信返回错误吗,就用这个吧,起码我测试微信这个接口的时候用postman测试返回的都是错误,而且一定要用JSON字符串,一定要是非常严格的JSON字符串。下面是这个方法: 

function api_notice_increment($url, $data){
 $ch = curl_init();
 $header = "Accept-Charset: utf-8";
 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
 curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
 curl_setopt($ch, CURLOPT_USERAGENT, &#39;Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)&#39;);
 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
 curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
 curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 $tmpInfo = curl_exec($ch);
 if (curl_errno($ch)) {
  curl_close( $ch );
  return $ch;
 }else{
  curl_close( $ch );
  return $tmpInfo;
 }

}

getTemporaryQrcode() 中有一个在配置文件中的参数给大家看下,其实就是微信接口链接: 
C('WECHAT_PUBLIC_GET_TEMPORARY_TICKET') = https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=##TOKEN##

这个接口的返回值是: 
{"ticket":"gQH47joAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL2taZ2Z3TVRtNzJXV1Brb3ZhYmJJAAIEZ23sUwMEmm3sUw==","expire_seconds":60,"url":"http:\/\/weixin.qq.com\/q\/kZgfwMTm72WWPkovabbI"}

其中ticket是让我们用来进行下一步调用的凭证,expire_seconds是二维码的有效期,url是我们生成的二维码扫描后打开的链接。所以如果我们自己实现了生成二维码的方法,就不用再进行下一步调用,我本人即在这一步就停止了,直接返回url的值,然后利用这个url的值生成二维码存在本地即可。PHP生成二维码可以使用phpqrcode,挺好用的。下一步也大致提一下:

3.2.2 获取二维码地址
请求方式: GET
接口:https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET
这个接口的返回值是一张图片,可以直接展示或者下载,我们有具体使用过,所以也不知道应该怎么展示。 

3.3 用户扫描二维码之后发生的事情
 3.3.1 扫描后发生了什么
上面提到了,用户扫描我们生成的临时二维码,如果用户未关注公众号,则首先会跳转到公众号的关注页面,点击关注后,会进入公众号的会话页面,同时会给我们设置的接口推送一个事件。如果用户已经关注了,用户微信会直接跳转到公众号会话页面,然后微信服务器会给我们设置的接口推送一个事件。

用户关注与否微信服务器给我们推送的事件是差不多的,只是新关注用户推送的事件中scene_id前面会加一个前缀。下面是微信公众平台文档的说明:

用户未关注时,进行关注后的事件推送

<xml><ToUserName><![CDATA[toUser]]></ToUserName>        //开发者微信号
<FromUserName><![CDATA[FromUser]]></FromUserName>       //发送者账号(openid)
<CreateTime>123456789</CreateTime>                //消息创建时间(整型)
<MsgType><![CDATA[event]]></MsgType>              //消息类型 event
<Event><![CDATA[subscribe]]></Event>              //事件类型(subscribe)
<EventKey><![CDATA[qrscene_123123]]></EventKey>        //事件KEY值,qrscene_为前缀,后面为二维码参数值
<Ticket><![CDATA[TICKET]]></Ticket>               //二维码ticke值,可以用来换取二维码图片
</xml>

 

用户已关注时的事件推送

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>        //开发者微信号
<FromUserName><![CDATA[FromUser]]></FromUserName>     //发送者账号(openid)
<CreateTime>123456789</CreateTime>             //消息创建时间
<MsgType><![CDATA[event]]></MsgType>     //消息类型event
<Event><![CDATA[SCAN]]></Event>               //事件类型 event
<EventKey><![CDATA[SCENE_VALUE]]></EventKey>   //事件key值,是一个32位无符号整数,即创建二维码时的二维码scene_id
<Ticket><![CDATA[TICKET]]></Ticket>      //二维码的ticke,可以用来换取二维码图片
</xml>

3.3.2 我们要做些什么

我们需要在自己填写的URL接口中接收这个事件,然后拿到我们需要的东西做我们想干的事儿。因为我要实现的功能比较简单,只需要拿到scene_id即可,因为这是我要展示给用户看的订单数据。下面是我写的接收和处理部分,比较简单,主要看一下应该怎么接收微信推送的事件: 

public function urlRedirect(){
  $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
  $postObj = simplexml_load_string($postStr, &#39;SimpleXMLElement&#39;, LIBXML_NOCDATA);
  $fromUsername = (string)$postObj->FromUserName;
  $EventKey = trim((string)$postObj->EventKey);
  $keyArray = explode("_", $EventKey);
  if (count($keyArray) == 1){   //已关注者扫描
   $this->sendMessage($fromUsername, $EventKey);
  }else{                   //未关注者关注后推送事件
   $this->sendMessage($fromUsername, $keyArray[1]);
  }
 }

我没有使用其他参数,只是根据不同的推送事件拿到我想要的订单ID,然后这时候其实相当于你在这里用公众号的客服在跟扫码的这个用户对话,上段代码中调用的sendMessage()是使用客户账号给扫码用户发送一个图文消息,因为我在拿scen_id的同时也拿到了用户的openid,可以利用这个给用户发送消息。

下面是sendMessage()方法: 

//给用户发送图文消息,点击跳转到报价页面
 public function sendMessage($openid,$orderId){
  $url = str_replace(&#39;##TOKEN##&#39;, getWechatAccessToken(), C(&#39;WECHAT_SEND_MESSAGE&#39;));
  $redirectUrl = str_replace("##ORDERID##", $orderId, str_replace("##OPENID##", $openid, C(&#39;WECHAT_REDIRECT_URL_PRE&#39;)));
  $orderInfo = M(&#39;order&#39;)->where(array(&#39;orderid&#39; => $orderId))->field(array(&#39;totalMoney&#39;, &#39;savedMoney&#39;, &#39;roomarea&#39;))->find();
  $description = str_replace("##ROOMAREA##", intval($orderInfo[&#39;roomarea&#39;] * 1.25), C(&#39;WECHAT_MESSAGE_BRIEF&#39;));
  $description = str_replace("##TOTALBUDGET##", $orderInfo[&#39;totalMoney&#39;], $description);
  $description = str_replace("##MARKETBUDGET##", $orderInfo[&#39;totalMoney&#39;]+$orderInfo[&#39;savedMoney&#39;], $description);
  $description = str_replace("##SAVEMONEY##", $orderInfo[&#39;savedMoney&#39;], $description);
  $dataStr = &#39;{"touser":"&#39; . $openid . &#39;","msgtype":"news","news":{"articles":[{"title":"&#39; . C(&#39;WECHAT_MESSAGE_TITLE&#39;) .
   &#39;","description":"&#39; . $description . &#39;","url":"&#39; . $redirectUrl . &#39;","picurl":"&#39; . C(&#39;WECHAT_MESSAGE_PICURL&#39;) . &#39;""}]}}&#39;;
  api_notice_increment($url, $dataStr);
 }

其中 C('WECHAT_SEND_MESSAGE') = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=##TOKEN##' 至于下面的一大段str_replace,就是在组给用户发送的文字而已,需要注意$dataStr的格式,这里面要求JSON字符串比较严格,必须所有的字符串都用双引号括起来。微信接口对POST参数的限制真心严格。

下面是微信公众平台开发者文档中要求发送图文消息的POST data格式: 

{
 "touser":"OPENID",
 "msgtype":"news",
 "news":{
  "articles": [
   {
    "title":"Happy Day",
    "description":"Is Really A Happy Day",
    "url":"URL",
    "picurl":"PIC_URL"
   },
   {
    "title":"Happy Day",
    "description":"Is Really A Happy Day",
    "url":"URL",
    "picurl":"PIC_URL"
   }
   ]
 }
}

其中url是用户点击这个消息之后打开的地址,这个时候我就组了一个自己网站的地址,是一个get请求地址,里面携带参数是用户的openid和订单id,这样用户点击开图文消息就可以看到自己刚才下单的内容了,因为需要在网页上展示用户的微信头像和昵称,所以我把openid也放到参数里,在页面加载前先拿到用户的个人信息和订单数据,再展示网页。这样流程:用户未登录下单 -> 生成微信二维码 -> 用户扫码关注公众号 -> 查看订单详细信息 就完成了。而且因为这个图文消息打开后的链接携带的参数是这个用户的额openid和其下单的订单ID,不管分享到哪儿,用什么浏览器打开都是可以访问的,且展示的也是这个用户的头像和昵称信息,这也是我要实现的一个效果。

总结:以上就是本篇文的全部内容,希望能对大家的学习有所帮助。

相关推荐:

php 变量引用与变量销毁机制详解

PHP实现微信JS-SDK接口选择相册及拍照并上传的方法

php版微信自定义回复功能详解

以上がPHP に基づいた WeChat 開発用のパラメーターを含む QR コードの使用を実装するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。