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 ...
随机推荐
- EsayUI + MVC + ADO.NET(项目架构)
项目目录 1.项目架构: http://www.cnblogs.com/liuxiaoji/p/3922506.html 2.仓储基础接口: http://www.cnblogs.com/liu ...
- 自定义 Git - 配置 Git
用git config配置 Git,要做的第一件事就是设置名字和邮箱地址: $ git config --global user.name "John Doe" $ git con ...
- C.【转】C语言字符串与数字相互转换
1.gcvt 把浮点数转成字符串 - CSDN博客.html(https://blog.csdn.net/dxuehui/article/details/52791412) 1.1. 函数名: gcv ...
- 力扣(LeetCode)219. 存在重复元素 II
给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值最大为 k. 示例 1: 输入: nums = ...
- Google Map 谷歌地图
<script> var map; function initMap() { var position = new google.maps.LatLng(1.539187, 103.647 ...
- angular2 学习笔记 (Typescript - Attribute & reflection & decorator)
更新 : 2018-11-27 { date: Date } 之前好像搞错了,这个是可以用 design:type 拿到的 { date: Date | null } 任何类型一但配上了 | 就 de ...
- WAMP环境配置
mysql 5.7.12 php 7.1 apache 24 windows 10 64bit 下载好代码后, 1.首先把更目录的sql.sql导入到数据库2.打开application\config ...
- sql 聚合函数和group by 联合使用
原文 很多时候单独使用聚合函数的时候觉得很容易,求个平均值,求和,求个数等,但是和分组一起用就有点混淆了,好记性不如烂笔头,所以就记下来以后看看. 常用聚合函数罗列 1 AVG() - 返回平均值 C ...
- Java 发送SOAP请求调用WebService,解析SOAP报文
https://blog.csdn.net/Peng_Hong_fu/article/details/80113196 记录测试代码 SoapUI调用路径 http://localhost:8082/ ...
- boke练习: category类的编辑修改,总是提示:该分类名称已经存在
boke练习: category类的编辑修改,总是提示:该分类名称已经存在 本利采用的dao是: jpaRepository方式 先看原始代码: category的实体类 @Entity public ...