php微信公众号开发
简单的事例总结:
wamp下载安装:https://sourceforge.net/projects/wampserver/
www目录里创建php文件weixin.php
<?php
header('Content-type:text');
define("TOKEN", "weixin");
define("ACCESS_TOKEN", "rYJURNEdhixEbmSIL5qZj0MtkK_o4Noo9c7inI-RKNvh0z7Mc6QwqTlo_x2aQYjrCwWeUt4mcPwmgCeFthzDyVVzrCCA-AOeoTrtrnL6Bt8MdH32h_36ZMoOvwGSdDMYRTIhADALNC");
$wechatObj = new wechatCallbackapiTest();
if (!isset($_GET['echostr'])) {
$wechatObj->responseMsg();
}else{
$wechatObj->valid();
} class wechatCallbackapiTest
{
public function valid()
{
$echoStr = $_GET["echostr"];
if($this->checkSignature()){
echo $echoStr;
exit;
}
} private function checkSignature()
{
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr); if($tmpStr == $signature){
return true;
}else{
return false;
}
} public function responseMsg()
{
$postStr = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : file_get_contents("php://input");
if (!empty($postStr)){
$this->logger("R ".$postStr);
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$RX_TYPE = trim($postObj->MsgType); switch ($RX_TYPE)
{
case "event":
$result = $this->receiveEvent($postObj);
break;
case "text":
$result = $this->receiveText($postObj);
break;
}
$this->logger("T ".$result);
echo $result;
}else {
echo "";
exit;
}
} private function receiveEvent($object)
{
$content = "";
switch ($object->Event)
{
case "subscribe":
$content = "蛋蛋你好!";
break;
case "unsubscribe":
$content = "取消关注";
break;
}
$result = $this->transmitText($object, $content);
return $result;
} //接收文本消息
private function receiveText($object)
{
$keyword = trim($object->Content);
$content = date("Y-m-d H:i:s",time())."\n妹妹你好!"; if(is_array($content)){
if (isset($content[0]['PicUrl'])){
$result = $this->transmitNews($object, $content);
}else if (isset($content['MusicUrl'])){
$result = $this->transmitMusic($object, $content);
}
}else{
$result = $this->transmitText($object, $content);
} return $result;
} private function transmitText($object, $content)
{
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";
$result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content);
return $result;
} private function transmitNews($object, $arr_item)
{
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>
</xml>"; $result = sprintf($newsTpl, $object->FromUserName, $object->ToUserName, time(), count($arr_item));
return $result;
} private function transmitMusic($object, $musicArray)
{
$itemTpl = "<Music>
<Title><![CDATA[%s]]></Title>
<Description><![CDATA[%s]]></Description>
<MusicUrl><![CDATA[%s]]></MusicUrl>
<HQMusicUrl><![CDATA[%s]]></HQMusicUrl>
</Music>"; $item_str = sprintf($itemTpl, $musicArray['Title'], $musicArray['Description'], $musicArray['MusicUrl'], $musicArray['HQMusicUrl']); $textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[music]]></MsgType>
$item_str
</xml>"; $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());
return $result;
} private function logger($log_content)
{
if(isset($_SERVER['HTTP_APPNAME'])){ //SAE
sae_set_display_errors(false);
sae_debug($log_content);
sae_set_display_errors(true);
}else if($_SERVER['REMOTE_ADDR'] != "127.0.0.1"){ //LOCAL
$max_size = 10000;
$log_filename = "log.xml";
if(file_exists($log_filename) and (abs(filesize($log_filename)) > $max_size)){unlink($log_filename);}
file_put_contents($log_filename, date('H:i:s')." ".$log_content."\r\n", FILE_APPEND);
}
}
} //创建菜单
function createMenu($data){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=".ACCESS_TOKEN);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
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)) {
return curl_error($ch);
}
curl_close($ch);
return $tmpInfo;
} //获取菜单
function getMenu(){
return file_get_contents("https://api.weixin.qq.com/cgi-bin/menu/get?access_token=".ACCESS_TOKEN);
} $data2 = '{
"button":[
{
"type":"view",
"name":"视频",
"url":"http://v.qq.com/"
},
{
"type":"view",
"name":"百度",
"url":"http://www.baidu.com/"
},
{
"name":"菜单",
"sub_button":[
{
"type":"view",
"name":"搜索",
"url":"http://www.soso.com/"
},
{
"name": "发送位置",
"type": "location_select",
"key": "rselfmenu_2_0"
}]
}]
}';
echo createMenu($data2); ?>
网页访问localhost//weixin.php
微信公众号需要服务器需要域名这时候我们可以在新浪云注册个域名,大概需要10块钱一个月的,上传代码
不想申请域名我们本地也可以,先注册个花生壳,localhost查看下ip地址,在c盘Windows/System32/drivers/etc/HOSTS文件设置下ip,然后花生壳映射下ip,当前主机,网页访问花生壳内容外网就可以访问我们的项目了
注册微信公众号并登陆https://mp.weixin.qq.com/,然后找到开发,开发者工具,找到公众平台测试号,接口配置信息修改,url写花生壳域名,Token随便写上面代码要用,我写的weixin
这时候手机打开微信扫下二维码就可以了
php微信公众号开发的更多相关文章
- 微信公众号开发(一)--验证服务器地址的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 ...
- C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件)
微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C ...
随机推荐
- C#_方法的重载
方法的重载是一种操作性多态,有的时候,可能需要在多个不同的实现中对不同的数据执行相同的逻辑操作,以writeline方法为例,有时可能想他传递一个整数.两者的具体实现肯定是不同的,但在逻辑上,这个方法 ...
- 学习笔记41—ttest误区
1.grapPad软件里面双T结果和matlab,EXCEl里面双T结果一致时,设置如下:
- MySQL学习(十二)
视图 view 在查询中,我们经常把查询结果当成临时表来看, view是什么?view可以看成一张虚拟表,是表通过某种运算得到的一个投影. 表的变化会影响到视图 既然视图只是表的某种查询的投影,所以主 ...
- Mac Anaconda 安装
下载地址 https://www.anaconda.com/download/#macos 选择对应的python 版本 安装 一路下一步 安装后打开如下 呵呵,此处装完,我的python 环境又从3 ...
- C# http监听之Nancy.net
通过winform或者是控制台应用程序监听http请求,之前使用的是微软的HttpListener,参考https://www.cnblogs.com/duanjt/p/5566336.html 然后 ...
- how-to-view-source-of-chrome-extension
https://gist.github.com/paulirish/78d6c1406c901be02c2d Option 1: Command-line download extension as ...
- Program Option Modifiers
Some option are 'boolean' and control behavior that can be turned on or off. --column-names option d ...
- 20165327 2017-2018-2 《Java程序设计》第2周学习总结
20165327 2017-2018-2 <Java程序设计>第2周学习总结 内容:教材第2.3章 内容小结: (一)标识符由字母.下划线.美元符号和数字组成, 并且第一个字符不能是数字字 ...
- LOJ6036编码
每个串拆成两个,都插入trie数. 把trie树建出来后,每一条从根到叶子的链上最多只能有一个变量为1. 这是个经典的前后缀优化2-sat建图的套路. 树上的做法也就是边dfs边做而已. #inclu ...
- python基础之字典以及增删改查
字典:字典是python中唯一的一个映射类型,主要形式为 dic = {key1:value,key2:value2,....} 字典中key的值是唯一的,主要关系到HASH算法,并且key的值必须是 ...