php 公众号开发
思考:
1,优先使用php扩展库的sdk,配合微信文档。
2,公众号开发比较简单,重在业务。
公众号关联与消息分发
<?php namespace app\wap\controller; use think\Controller;
\think\Loader::addNamespace('data', 'data/');
use data\extend\WchatOauth;
use data\service\Config;
use data\service\WebSite;
use data\service\Weixin; class Wchat extends Controller
{ public $wchat; public $weixin_service; public $author_appid; public $instance_id; public $style; public function __construct()
{
parent::__construct();
$this->wchat = new WchatOauth(); // 微信公众号相关类 $this->weixin_service = new Weixin();
// 使用那个手机模板
$config = new Config();
$use_wap_template = $config->getUseWapTemplate(0); if (empty($use_wap_template)) {
$use_wap_template['value'] = 'default_new';
}
$this->style = "wap/" . $use_wap_template['value'] . "/";
$this->assign("style", "wap/" . $use_wap_template['value']); $this->getMessage();
} /**
* ************************************************************************微信公众号消息相关方法 开始******************************************************
*/
/**
* 关联公众号微信
*/
public function relateWeixin()
{
$sign = request()->get('signature', '');
if (isset($sign)) {
$signature = $sign;
$timestamp = request()->get('timestamp');
$nonce = request()->get('nonce'); $token = "TOKEN";
$config = new Config();
$this->instance_id = 0;
$wchat_config = $config->getInstanceWchatConfig($this->instance_id);
if (! empty($wchat_config["value"]["token"])) {
$token = $wchat_config["value"]["token"];
} $tmpArr = array(
$token,
$timestamp,
$nonce
); sort($tmpArr, SORT_STRING);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr); if ($tmpStr == $signature) {
$echostr = request()->get('echostr', '');
if (! empty($echostr)) {
ob_clean();
echo $echostr;
} return 1;
} else {
return 0;
}
}
} public function templateMessage()
{
$media_id = request()->get('media_id', 0);
$weixin = new Weixin();
$info = $weixin->getWeixinMediaDetailByMediaId($media_id);
if (! empty($info["media_parent"])) {
$website = new WebSite();
$website_info = $website->getWebSiteInfo();
$this->assign("website_info", $website_info);
$this->assign("info", $info);
return view($this->style . 'Wchat/templateMessage');
} else {
echo "图文消息没有查询到";
}
} /**
* 微信开放平台模式(需要对消息进行加密和解密)
* 微信获取消息以及返回接口
*/
public function getMessage()
{
$from_xml = file_get_contents('php://input');
if (empty($from_xml)) {
return;
}
$signature = request()->get('msg_signature', '');
$signature = request()->get('timestamp', '');
$nonce = request()->get('nonce', '');
$url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . '?' . $_SERVER['QUERY_STRING'];
$ticket_xml = $from_xml;
$postObj = simplexml_load_string($ticket_xml, 'SimpleXMLElement', LIBXML_NOCDATA); $this->instance_id = 0;
if (! empty($postObj->MsgType)) {
switch ($postObj->MsgType) {
case "text":
$weixin = new Weixin();
// 用户发的消息 存入表中
$weixin->addUserMessage((string) $postObj->FromUserName, (string) $postObj->Content, (string) $postObj->MsgType);
$resultStr = $this->MsgTypeText($postObj);
break;
case "event":
$resultStr = $this->MsgTypeEvent($postObj);
break;
default:
$resultStr = "";
break;
}
}
if (! empty($resultStr)) {
echo $resultStr;
} else {
echo '';
}
exit();
} /**
* 文本消息回复格式
*
* @param unknown $postObj
* @return Ambigous <void, string>
*/
private function MsgTypeText($postObj)
{
$funcFlag = 0; // 星标
$wchat_replay = $this->weixin_service->getWhatReplay($this->instance_id, (string) $postObj->Content);
// 判断用户输入text
if (! empty($wchat_replay)) { // 关键词匹配回复
$contentStr = $wchat_replay; // 构造media数据并返回
} elseif ($postObj->Content == "uu") {
$contentStr = "shopId:" . $this->instance_id;
} elseif ($postObj->Content == "TESTCOMPONENT_MSG_TYPE_TEXT") {
$contentStr = "TESTCOMPONENT_MSG_TYPE_TEXT_callback"; // 微店插件功能 关键词,预留口
} elseif (strpos($postObj->Content, "QUERY_AUTH_CODE") !== false) {
$get_str = str_replace("QUERY_AUTH_CODE:", "", $postObj->Content);
$contentStr = $get_str . "_from_api"; // 微店插件功能 关键词,预留口
} else {
$content = $this->weixin_service->getDefaultReplay($this->instance_id);
if (! empty($content)) {
$contentStr = $content;
} else {
$contentStr = '';
}
}
if (is_array($contentStr)) {
$resultStr = $this->wchat->event_key_news($postObj, $contentStr);
} elseif (! empty($contentStr)) {
$resultStr = $this->wchat->event_key_text($postObj, $contentStr);
} else {
$resultStr = '';
}
return $resultStr;
} /**
* 事件消息回复机制
*/
// 事件自动回复 MsgType = Event
private function MsgTypeEvent($postObj)
{
$contentStr = "";
switch ($postObj->Event) {
case "subscribe": // 关注公众号
$str = $this->wchat->get_fans_info($postObj->FromUserName);
if (preg_match("/^qrscene_/", $postObj->EventKey)) {
$source_uid = substr($postObj->EventKey, 8);
$_SESSION['source_shop_id'] = $this->instance_id;
$_SESSION['source_uid'] = $source_uid;
} elseif (! empty($_SESSION['source_uid'])) {
$source_uid = $_SESSION['source_uid'];
$_SESSION['source_shop_id'] = $this->instance_id;
} else {
$source_uid = 0;
}
$Userstr = json_decode($str);
$nickname = base64_encode($Userstr->nickname);
$nickname_decode = preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $Userstr->nickname);
$headimgurl = $Userstr->headimgurl;
$sex = $Userstr->sex;
$language = $Userstr->language;
$country = $Userstr->country;
$province = $Userstr->province;
$city = $Userstr->city;
$district = "无";
$openid = $Userstr->openid;
if (! empty($Userstr->unionid)) {
$unionid = $Userstr->unionid;
} else {
$unionid = '';
}
$subscribe_date = date('Y/n/j G:i:s', (int) $postObj->CreateTime);
$memo = $Userstr->remark;
$weichat_subscribe = $this->weixin_service->addWeixinFans((int) $source_uid, $this->instance_id, $nickname, $nickname_decode, $headimgurl, $sex, $language, $country, $province, $city, $district, $openid, '', 1, $memo, $unionid); // 关注
// 添加关注回复
$content = $this->weixin_service->getSubscribeReplay($this->instance_id);
if (! empty($content)) {
$contentStr = $content;
}
// 构造media数据并返回 */
break;
case "unsubscribe": // 取消关注公众号
$openid = $postObj->FromUserName;
$weichat_unsubscribe = $this->weixin_service->WeixinUserUnsubscribe($this->instance_id, (string) $openid);
break;
case "VIEW": // VIEW事件 - 点击菜单跳转链接时的事件推送
/* $this->wchat->weichat_menu_hits_view($postObj->EventKey); //菜单计数 */
$contentStr = "";
break;
case "SCAN": // SCAN事件 - 用户已关注时的事件推送 - 扫描带参数二维码事件
$openid = $postObj->FromUserName;
$data = $postObj->EventKey;
$user_bound = $this->weixin_service->userBoundParent((string) $openid, $data);
$content = $this->weixin_service->getSubscribeReplay($this->instance_id);
if (! empty($content)) {
$contentStr = $content;
}
break;
case "CLICK": // CLICK事件 - 自定义菜单事件
$menu_detail = $this->weixin_service->getWeixinMenuDetail($postObj->EventKey);
$media_info = $this->weixin_service->getWeixinMediaDetail($menu_detail['media_id']);
$contentStr = $this->weixin_service->getMediaWchatStruct($media_info); // 构造media数据并返回 */
break;
default:
break;
}
// $contentStr = $postObj->Event."from_callback";//测试接口正式部署之后注释不要删除
if (is_array($contentStr)) {
$resultStr = $this->wchat->event_key_news($postObj, $contentStr);
} else {
$resultStr = $this->wchat->event_key_text($postObj, $contentStr);
}
return $resultStr;
} /**
* ************************************************************************微信公众号消息相关方法 结束******************************************************
*/
}
微信接口调用
<?php
namespace data\extend; use think\Cache as cache;
use data\service\Config;
use think;
use think\Log; class WchatOauth
{ public $author_appid; public $token; /**
* 构造函数
*
* @param unknown $shop_id
*/
public function __construct($appid = '')
{
$this->author_appid = 'instanceid_0';
} /**
* ***********************************************************************基础信息*************************************************
*/
/**
* 公众号获取access_token
*
* @return unknown
*/
private function get_access_token()
{
// 公众平台模式获取token
$token = $this->single_get_access_token();
return $token;
} /**
* 公众平台账户获取token
*/
private function single_get_access_token()
{
$config = new Config();
$wchat_config = $config->getInstanceWchatConfig(0);
$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $wchat_config['value']['appid'] . '&secret=' . $wchat_config['value']['appsecret'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$a = curl_exec($ch);
$strjson = json_decode($a);
if($strjson == false || empty($strjson))
{
return '';
}else{
$token = $strjson->access_token;
if (empty($token)) {} else {
// 注意如果是多用户需要
cache::set('token-' . $this->author_appid, $token, 3600);
}
return $token;
} } /**
* 微信数据获取
*
* @param unknown $url
* @param unknown $data
* @param string $needToken
* @return string|unknown
*/
private function get_url_return($url, $data = '', $needToken = false)
{
// 第一次为空,则从文件中读取
if (empty($this->token)) {
$this->token = cache::get('token-' . $this->author_appid);
}
// 为空则重新取值
if (empty($this->token) or $needToken) { $this->get_access_token();
$this->token = cache::get('token-' . $this->author_appid);
}
$newurl = sprintf($url, $this->token);
$curl = curl_init(); // 创建一个新url资源
curl_setopt($curl, CURLOPT_URL, $newurl);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
if (! empty($data)) {
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$AjaxReturn = curl_exec($curl);
// curl_close();
$strjson = json_decode($AjaxReturn);
if (! empty($strjson->errcode)) {
switch ($strjson->errcode) {
case 40001:
return $this->get_url_return($url, $data, true); // 获取access_token时AppSecret错误,或者access_token无效
break;
case 40014:
return $this->get_url_return($url, $data, true); // 不合法的access_token
break;
case 42001:
return $this->get_url_return($url, $data, true); // access_token超时
break;
case 45009:
return json_encode(array(
"errcode" => - 45009,
"errmsg" => "接口调用超过限制:" . $strjson->errmsg
));
break;
case 41001:
return json_encode(array(
"errcode" => - 41001,
"errmsg" => "缺少access_token参数:" . $strjson->errmsg
));
break;
default:
return json_encode(array(
"errcode" => - 41000,
"errmsg" => $strjson->errmsg
)); // 其他错误,抛出
break;
}
} else {
return $AjaxReturn;
}
} /**
* ***********************************************************************基础信息*************************************************
*/
/**
* *************************************************微信回复消息部分 开始**************************************
*/
/**
* 返回文本消息组装xml
*
* @param unknown $postObj
* @param unknown $content
* @param number $funcFlag
* @return string
*/
public function event_key_text($postObj, $content, $funcFlag = 0)
{
if (! empty($content)) {
$xmlTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
<FuncFlag>%d</FuncFlag>
</xml>";
$resultStr = sprintf($xmlTpl, $postObj->FromUserName, $postObj->ToUserName, time(), $content, $funcFlag);
return $resultStr;
}else{
return '';
}
} /**
* 返回图文消息组装xml
*
* @param unknown $postObj
* @param unknown $arr_item
* @param number $funcFlag
* @return void|string
*/
public function event_key_news($postObj, $arr_item, $funcFlag = 0)
{
// 首条标题28字,其他标题39字
if (! is_array($arr_item)) {
return;
}
$itemTpl = "<item>
<Title><![CDATA[%s]]></Title>
<Description><![CDATA[%s]]></Description>
<PicUrl><![CDATA[%s]]></PicUrl>
<Url><![CDATA[%s]]></Url>
</item>
";
$item_str = "";
foreach ($arr_item as $item) {
$item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);
}
$newsTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<Content><![CDATA[]]></Content>
<ArticleCount>%s</ArticleCount>
<Articles>
$item_str</Articles>
<FuncFlag>%s</FuncFlag>
</xml>";
$resultStr = sprintf($newsTpl, $postObj->FromUserName, $postObj->ToUserName, time(), count($arr_item), $funcFlag);
return $resultStr;
} /**
* *************************************************微信回复消息部分 结束******************************************************************************
*/ /**
* **********************************************************************************微信获取粉丝信息 开始*********************************************
*/ /**
* 微信公众号拉取粉丝信息
*
* @param unknown $next_openid
* @return mixed
*/
public function get_fans_list($next_openid)
{
$strjson = $this->get_url_return("https://api.weixin.qq.com/cgi-bin/user/get?access_token=%s&next_openid={$next_openid}");
$strarray = json_decode($strjson, true);
return $strarray;
}
/**
* 批量获取用户粉丝信息
* @return mixed
*/
public function get_fans_info_list($openids)
{
$strjson = $this->get_url_return("https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=%s", $openids);
$strarray = json_decode($strjson, true);
return $strarray;
} /**
* 获取粉丝信息(通过openID)
*
* @param unknown $openid
* @return Ambigous <string, \data\extend\unknown, mixed>
*/
public function get_fans_info($openid)
{
$url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid={$openid}";
return $this->get_url_return($url);
} /**
* 获取openid(前台会员)
*
* @return unknown
*/
public function get_member_access_token()
{
if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger')) {
// 通过code获得openid
if (empty($_GET['code'])) {
// 触发微信返回code码
$baseUrl = request()->url(true);
$url = $this->get_single_authorize_url($baseUrl, "123"); Header("Location: $url");
exit();
} else {
// 获取code码,以获取openid
$code = $_GET['code']; $data = $this->get_single_access_token($code);
return $data;
}
}
} /**
* 获取OAuth2授权access_token(微信公众平台模式)
*
* @param string $code
* 通过get_authorize_url获取到的code
*/
public function get_single_access_token($code = '')
{
$config = new Config();
$wchat_config = $config->getInstanceWchatConfig(0);
$token_url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $wchat_config['value']['appid'] . '&secret=' . $wchat_config['value']['appsecret'] . '&code=' . $code . '&grant_type=authorization_code';
$data = $this->get_url_return($token_url);
$token_data = json_decode($data, true);
return $token_data;
} /**
* 获取微信OAuth2授权链接snsapi_base
*
* @param string $redirect_uri
* 跳转地址
* @param mixed $state
* 参数
* 不弹出授权页面,直接跳转,只能获取用户openid
*/
public function get_single_authorize_url($redirect_url = '', $state = '')
{
$redirect_url = urlencode($redirect_url);
$config = new Config();
$wchat_config = $config->getInstanceWchatConfig(0);
return "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $wchat_config['value']['appid'] . "&redirect_uri=" . $redirect_url . "&response_type=code&scope=snsapi_userinfo&state={$state}#wechat_redirect";
} /**
* 获取会员对于公众号信息
*
* @param unknown $appid
*/
public function get_oauth_member_info($token)
{
$token_url = "https://api.weixin.qq.com/sns/userinfo?access_token=" . $token['access_token'] . "&openid=" . $token['openid'] . "&lang=zh_CN";
$data = $this->get_url_return($token_url);
return $data;
}
// 单发消息
public function send_message($openid, $msgtype, $content)
{
$json = '{"touser":"%s","msgtype":"%s","text":{"content":"%s"}}';
$jsondata = sprintf($json, $openid, $msgtype, $content);
$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s";
return $this->get_url_return($url, $jsondata);
}
// 群发消息
public function send_group_message($jsondata)
{
$url = "https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token=%s";
return $this->get_url_return($url, $jsondata);
} // 基础支持: 多媒体文件上传接口 /media/upload媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb)
// form-data中媒体文件标识,有filename、filelength、content-type等信息
public function upload_media($type)
{
$url = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=" . $type;
return $this->get_url_return($url);
}
// 基础支持: 下载多媒体文件接口 /media/get
public function get_modia($media_id)
{
$url = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=" . $media_id;
return $this->get_url_return($url);
} /**
* **********************************************************************************微信获取粉丝信息 结束*********************************************
*/
/**
* 微信公众号自定义菜单
*
* @param unknown $appid
* @param unknown $jsonmenu
* @return Ambigous <string, \data\extend\unknown, mixed>
*/
public function menu_create($jsonmenu)
{
$url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=%s";
$result = $this->get_url_return($url, $jsonmenu);
return $result;
} /**
* **********************************************************************************微信推广二维码 开始*********************************************
*/
// 生成永久二维码图片地址
public function ever_qrcode($data_id)
{
if (! empty($data_id)) {
$data_array = array(
'action_name' => 'QR_LIMIT_STR_SCENE',
'action_info' => array(
'scene' => array(
'scene_str' => $data_id
)
)
); $json = json_encode($data_array);
return $this->qrcode_create($json);
}
} /**
* 推广支持: 创建二维码ticket接口 /qrcode/create && 换取二维码 /showqrcode
*
* @return src [二维码图片地址]
*/
// 生成二维码基类函数
public function qrcode_create($json)
{
// 临时二维码请求说明POST-json:{"action_name": "QR_LIMIT_STR_SCENE", "action_info": {"scene": {"scene_str": "123"}}}
// 永久二维码请求说明POST-json:POST数据例子:{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": 123}}}
// action_name 二维码类型,QR_SCENE为临时,QR_LIMIT_SCENE为永久,QR_LIMIT_STR_SCENE为永久的字符串参数值
$url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=%s"; $jsonReturn = $this->get_url_return($url, $json);
$jsonReturn = json_decode($jsonReturn);
if (! empty($jsonReturn->ticket)) {
$ticket = $jsonReturn->ticket;
// $QrCode = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=".$ticket;
$QrCode = $jsonReturn->url;
} else {
$QrCode = '';
} return $QrCode;
} /**
* 把微信生成的图片存入本地
*
* @param [type] $username
* [用户名]
* @param [string] $LocalPath
* [要存入的本地图片地址]
* @param [type] $weixinPath
* [微信图片地址]
*
* @return [string] [$LocalPath]失败时返回 FALSE
*/
public function save_weixin_img($local_path, $weixin_path)
{
$weixin_path_a = str_replace("https://", "http://", $weixin_path);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $weixin_path_a);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_USERAGENT, _USERAGENT_);
curl_setopt($ch, CURLOPT_REFERER, _REFERER_);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$r = curl_exec($ch);
curl_close($ch);
if (! empty($local_path) && ! empty($weixin_path_a)) {
$msg = file_put_contents($local_path, $r);
}
// 执行图片压缩
$image = think\Image::open($local_path);
$image->thumb(120, 120, \think\Image::THUMB_CENTER)->save($local_path);
return $local_path;
} /**
* **********************************************************************************微信推广二维码 结束*********************************************
*/
/**
* 功能说明:从微信选择地址 - 创建签名SHA1
*
* @param array $Parameters
* string1加密
*/
public function sha1_sign($Parameters)
{
$signPars = '';
ksort($Parameters);
foreach ($Parameters as $k => $v) {
if ("" != $v && "sign" != $k) {
if ($signPars == '')
$signPars .= $k . "=" . $v;
else
$signPars .= "&" . $k . "=" . $v;
}
}
$sign = sha1($signPars);
return $sign;
} /**
* 产生随机字符串,不长于32位
*
* @param int $length
* @return 产生的随机字符串
*/
public function get_nonce_str($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i ++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
} /**
* 格式化参数格式化成url参数
*/
public function to_url_param()
{
$buff = "";
foreach ($this->values as $k => $v) {
if ($k != "sign" && $v != "" && ! is_array($v)) {
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
} /**
* *************分享接口*********************************************************************************************
*/
// jsapi_ticket JS接口的临时票据
public function jsapi_ticket()
{
$url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi";
$ticket = json_decode($this->get_url_return($url), true);
return $ticket['ticket'];
} /**
* *************模板消息接口*********************************************************************************************
*/
// 获取模板ID POST请求
public function templateID($templateno)
{
$templateno_array = array(
"template_id_short" => $templateno
);
$json = json_encode($templateno_array);
$url = "https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token=%s";
return $this->get_url_return($url, $json);
} // 模版消息发送
public function templateMessageSend($openid, $templateId, $url, $first, $keyword1, $keyword2, $keyword3, $keyword4, $remark)
{
$array = array(
'touser' => $openid,
'template_id' => $templateId,
'url' => $url,
'topcolor' => '#FF0000',
'data' => array(
'first' => array(
'value' => $first,
'color' => '#173177'
),
'keyword1' => array(
'value' => $keyword1,
'color' => '#173177'
),
'keyword2' => array(
'value' => $keyword2,
'color' => '#173177'
),
'keyword3' => array(
'value' => $keyword3,
'color' => '#173177'
),
'keyword4' => array(
'value' => $keyword4,
'color' => '#173177'
),
'remark' => array(
'value' => $remark,
'color' => '#173177'
)
)
);
$json = json_encode($array);
$url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";
return $this->get_url_return($url, $json);
} public function MessageSendToUser($openid, $msg_type, $content)
{
$array = array(
'touser' => $openid
);
switch ($msg_type) {
case "text":
$array['msgtype'] = 'text';
$array['text'] = array(
'content' => $content
);
break;
}
$json = json_encode($array);
$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s";
return $this->get_url_return($url, $json);
} /**
* 获取openid(前台会员)
*
* @return unknown
*/
public function get_weixin_member_access_token($code)
{
// 通过code获得openid
if (empty($code)) {
// 触发微信返回code码
$baseUrl = request()->url(true);
$url = $this->get_single_authorize_url($baseUrl, "123"); Header("Location: $url");
exit();
} else {
// 获取code码,以获取openid
$data = $this->get_single_access_token($code);
return $data;
}
}
}
微信统一消息
微信清缓存
http://debugx5.qq.com
http://debugtbs.qq.com
php 公众号开发的更多相关文章
- 快递Api接口 & 微信公众号开发流程
之前的文章,已经分析过快递Api接口可能被使用的需求及场景:今天呢,简单给大家介绍一下微信公众号中怎么来使用快递Api接口,来完成我们的需求和业务场景. 开发语言:Nodejs,其中用到了Neo4j图 ...
- 微信公众号开发(一)--验证服务器地址的Java实现
现在主流上都用php写微信公众号后台,其实作为后端语言之一的java也可以实现. 这篇文章将对验证服务器地址这一步做出实现. 参考资料:1.慕课网-<初识java微信公众号开发>,2.微信 ...
- C#微信公众号开发系列教程三(消息体签名及加解密)
http://www.cnblogs.com/zskbll/p/4139039.html C#微信公众号开发系列教程一(调试环境部署) C#微信公众号开发系列教程一(调试环境部署续:vs远程调试) C ...
- C#微信公众号开发系列教程二(新手接入指南)
http://www.cnblogs.com/zskbll/p/4093954.html 此系列前面已经更新了两篇博文了,都是微信开发的前期准备工作,现在切入正题,本篇讲解新手接入的步骤与方法,大神可 ...
- 微信公众号开发系列教程一(调试环境部署续:vs远程调试)
http://www.cnblogs.com/zskbll/p/4080328.html 目录 C#微信公众号开发系列教程一(调试环境部署) C#微信公众号开发系列教程一(调试环境部署续:vs远程调试 ...
- NET微信公众号开发-5.0微信支付(待测试)
开发前准备. 1.0微信支付官方开发者文档 2.0官方demo下载 我们用c#所以选择.net版本 不过这个官方的demo根本跑步起来 3.0官方demo运行起来解决方案 4.0微信支付官方.net版 ...
- .NET开发者如何愉快的进行微信公众号开发
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:这篇文章只是一个如何提高开发效率的简单指导和记录,不会涉及具体的微信公众号开发内容. ...
- 微信公众号开发之被逼学web服务端1-----使用SecureCRT连接Linux服务器
做Android的进新公司后安排做微信公众号开发,这基本是后台和前端的活都要由小白的我来做,这两天基本成鸭子了,被填的满满的,却还是不够,博文仅作记录,希望能给后来的小白一点参考吧 今天做的是如何配置 ...
- 利用OpenShift托管Node.js Web服务进行微信公众号开发
最近写了一个微信的翻译机器人.用户只要关注该公众号,发送英文的消息,就能收到中文翻译的回复.有兴趣的读者可以扫描下面的二维码关注该公众号,尝试发送英文单词试试看.(有时候第一次发送单词会收到“该公众号 ...
- .net微信公众号开发——消息与事件
作者:王先荣 本文介绍如何处理微信公众号开发中的消息与事件,包括:(1)消息(事件)概况:(2)验证消息的真实性:(3)解析消息:(4)被动回复消息:(5)发送其他消息. 开源项目地址:h ...
随机推荐
- Windows环境下Nginx配置本地虚拟域名
进入conf文件夹,新建servers文件夹: 将内部的server配置段提取单独放在一个文件里,存到了conf/servers下,以方便配置多个虚拟主机. 并在nginx.conf里http配置段内 ...
- Vue与React的区别
对已经了解的内容,做几点介绍,并不全面,后期会不断更新~ React与Vue都是组件化的开发框架,整体功能类似. 一.数据处理模式(单项 or 双向): React推崇单项数据流的处理模式,数据不可以 ...
- ABP框架迁移到Mysql
ABP框架 .NetCore3.x版本 1.首先找到xxx.Core 项目,添加引用Microsoft.EntityFrameworkCore.Tools 2.找到xxx.EntityFramewor ...
- 《自拍教程21》mediainfo_多媒体文件查看工具
mediainfo命令介绍 mediainfo.exe(Linux/iMac下是未带后缀的mediainfo), 是一款音视频图片文件的信息查询工具, 常用于查看多媒体文件的视频流信息,音频流信息,字 ...
- 简单配置让iterm2用得更爽
同步自本人独立博客:https://liushiming.cn/2020/01/15/awesome-iterm2-config/ 概述 iterm2比mac原生的terminal好用很多,是mac下 ...
- Xilinx FPGA控制器的Everspin STT-DDR4设计指南
自旋转移扭矩磁阻随机存取存储器(STT-MRAM)是一种持久性存储技术,可利用各种工业标准接口提供性能,持久性和耐用性. Everspin推出了STT-MRAM产品,该产品利用称为JE-DDR4的JE ...
- 折腾vue--环境搭建(一)
1.安装nodejs nodejs下载地址:https://nodejs.org/en/ 2.检测nodejs //检测nodejs版本 node -v //检测npm npm –v 3.安装vue ...
- 建立基于docker的编译环境
如果我们要在一台开发主机上搭一个编译环境,我们需要安装一堆依赖库和编译工具.如果我们有多个不同的项目同时进行,这些项目的编译工具和依赖库又都不一样,如果我们把这些东西全都塞到一台机器里,会不会有冲突呢 ...
- element使用
官方网址: 点击 全局使用 1.创建项目 vue init webpack vue-ele 配置 2.安装依赖 npm install 3.安装loader模块(开发) npm install sty ...
- [Python]PyCharm中%matplotlib inline报错
%matplotlib作用 是在使用jupyter notebook 或者 jupyter qtconsole的时候,才会经常用到%matplotlib,也就是说那一份代码可能就是别人使用jupyte ...