├── README.md ├── 19、JS-SDK文件接入.php ├── 21、JS-SDK使用实例.php ├── 4、将错误信息写入文件.php ├── 12、PHP微信开发 获取用户地理位置信息-经纬度.php ├── 10、PHP微信开发,静默授权获取用户信息.php ├── 2、微信自动回复(文字).php ├── 16、PHP微信开发 生成短链接.php ├── 11、PHP微信开发之通过CODE参数获取用户信息.php ├── 3、微信自动回复(图文).php ├── 15、PHP微信开发 扫描二维码推送事件.php ├── 17、PHP微信开发 上传临时素材.php ├── 18、PHP微信开发 上传永久素材.php ├── 9、PHP微信开发 获取用户信息之关注时获取.php ├── 14、PHP微信开发 生成带参数的二维码 - 永久版.php ├── 13、PHP微信开发 生成带参数的二维码 - 临时版.php ├── 1、微信接入示例代码解说.php ├── 7、微信Access_Token中控器.php ├── 5、微信取消与关注事件.php ├── 8、PHP微信开发对自定义菜单进行改删查.php ├── 6、微信语音与图片识别.php └── 20、PHP微信开发 JS-SDK配置,jsapi_ticket权限签名获取.php /README.md: -------------------------------------------------------------------------------- 1 | 微信开发源码 2 | =============================================== 3 | 4 | 小黄牛 5 | ----------------------------------------------- 6 | 7 | ### 1731223728@qq.com 8 | 9 | 这是我在2016年刚接触微信开发时写一些源码,里面注释很多,希望对刚接触微信开发的同学有所帮助。 10 | -------------------------------------------------------------------------------- /19、JS-SDK文件接入.php: -------------------------------------------------------------------------------- 1 | 公众号设置 -> 功能设置 -> 下载验证文件上传至微信认证域名根目录或指定目录 13 | + 2、填写JS接口安全域名,如果是带目录,需要把目录填写完整,如果是根目录,域名后需要带/符号,提交保存 14 | + 3、在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js 15 | + 4、如需使用摇一摇周边功能,请引入 jweixin-1.1.0.js 16 | + 5、获得jsapi_ticket签名票据,填入以下JS配置文件(将在下节讲解) 17 | +---------------------------------------------------------------------------------------------------------------------------------------------- 18 | */ 19 | 20 | ?> 21 | 22 | 23 | 33 | 34 | -------------------------------------------------------------------------------- /21、JS-SDK使用实例.php: -------------------------------------------------------------------------------- 1 | GetToken()); 7 | require_once 'Jsapi_Ticket.php'; 8 | $WeiXin = new WeiXin(); 9 | # 获取签名 10 | $data = $WeiXin->GetTicket(); 11 | ?> 12 | 13 | 14 | 15 | 16 | 无标题文档 17 | 18 | 19 | 20 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /4、将错误信息写入文件.php: -------------------------------------------------------------------------------- 1 | '这只是个测试', 17 | 'toUsername' => '12sdzx3a1s', 18 | 'txt' => '测试完成' 19 | ]; 20 | $this->Error_Log($array,true); 21 | } 22 | /** 23 | * @Title : 记录错误信息与查看部分信息 24 | * @Author : 小黄牛 25 | * @param array : $Arr_Title 一个一维数组自定义内容 26 | * @param bool : $Arr_Error 是否插入系统错误信息 27 | * @param string : $File 日志名 28 | * @return : 无 29 | */ 30 | private function Error_Log($Arr_Title,$Arr_Error=false,$File='Error_log.log'){ 31 | # 不是数组中断程序 32 | if (!is_array($Arr_Title)) {return false;} 33 | # 定义一个空的变量,用于存放日志TXT实体 34 | $Error_TXT = "自定义信息如下:\r\n"; 35 | # 解析Arr_Title 自定义日志内容 36 | foreach ($Arr_Title as $key=>$val){ 37 | $Error_TXT .= $key.':'.$val."\r\n"; 38 | } 39 | 40 | # 判断系统错误显示是否开启 41 | if ($Arr_Error === true) { 42 | # 获取刚发生的错误信息,并返回数组,无错返回null 43 | $Arr_Error = error_get_last(); 44 | # 不为空则执行错误解析 45 | if (isset($Arr_Error)) { 46 | $Error_TXT .= "系统错误信息如下:\r\n"; 47 | # 解析$Arr_Errore 系统错误信息 48 | foreach ($Arr_Title as $key=>$val){ 49 | $Error_TXT .= $key.':'.$val."\r\n"; 50 | } 51 | } 52 | } 53 | 54 | # 最后再写入两个换行符,以便追加查看 55 | $Error_TXT .= "\r\n\r\n"; 56 | # 最后写入日志 57 | error_log($Error_TXT,3,$File); 58 | } 59 | } 60 | 61 | $test = new WeiXin_Error(); 62 | $test->Test(); 63 | -------------------------------------------------------------------------------- /12、PHP微信开发 获取用户地理位置信息-经纬度.php: -------------------------------------------------------------------------------- 1 | responseMsg(); 18 | 19 | 20 | class wechatCallbackapiTest { 21 | 22 | public function responseMsg() { 23 | # 获得数据包的信息 24 | $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; 25 | 26 | # 如果数据包内的信息不为空 27 | if (!empty($postStr)){ 28 | # XML文件的解析依赖libxml库,libxml_disable_entity_loader函数,是为了安全性,防止入侵者通过协议注入XML向服务器发起攻击 29 | libxml_disable_entity_loader(true); 30 | # 把XML编译成一个Class 31 | $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); 32 | # rx_type : 请求类型 33 | $rx_type = trim($postObj->MsgType); 34 | # rx_event : 操作的事件 35 | $rx_event = $postObj->Event; 36 | 37 | switch ($rx_event){ 38 | # 地理位置事件消息 - 大写 39 | case 'LOCATION': 40 | # 调用日志记录-方便出错则查看 41 | $this->Error_Log(array( 42 | '纬度' => $postObj->Latitude, 43 | '经度' => $postObj->Longitude, 44 | '精度' => $postObj->Precision 45 | ),false); 46 | break; 47 | } 48 | 49 | } 50 | } 51 | 52 | /** 53 | * @Title : 记录错误信息与查看部分信息 54 | * @Author : 小黄牛 55 | * @param array : $Arr_Title 一个一维数组自定义内容 56 | * @param bool : $Arr_Error 是否插入系统错误信息 57 | * @param string : $File 日志名 58 | * @return : 无 59 | */ 60 | private function Error_Log($Arr_Title,$Arr_Error=false,$File='Error_log.log'){ 61 | # 不是数组中断程序 62 | if (!is_array($Arr_Title)) {return false;} 63 | # 定义一个空的变量,用于存放日志TXT实体 64 | $Error_TXT = "自定义信息如下:\r\n"; 65 | # 解析Arr_Title 自定义日志内容 66 | foreach ($Arr_Title as $key=>$val){ 67 | $Error_TXT .= $key.':'.$val."\r\n"; 68 | } 69 | 70 | # 判断系统错误显示是否开启 71 | if ($Arr_Error === true) { 72 | # 获取刚发生的错误信息,并返回数组,无错返回null 73 | $Arr_Error = error_get_last(); 74 | # 不为空则执行错误解析 75 | if (isset($Arr_Error)) { 76 | $Error_TXT .= "系统错误信息如下:\r\n"; 77 | # 解析$Arr_Errore 系统错误信息 78 | foreach ($Arr_Title as $key=>$val){ 79 | $Error_TXT .= $key.':'.$val."\r\n"; 80 | } 81 | } 82 | } 83 | 84 | # 最后再写入两个换行符,以便追加查看 85 | $Error_TXT .= "\r\n\r\n"; 86 | # 最后写入日志 87 | error_log($Error_TXT,3,$File); 88 | } 89 | } -------------------------------------------------------------------------------- /10、PHP微信开发,静默授权获取用户信息.php: -------------------------------------------------------------------------------- 1 | 1、进入微信测试号,修改网页授权获取用户基本信息为www.junphp.com 2 | 2、在根目录新建一个oauth2.php文件,写入以下代码 3 | 4 | 5 | responseMsg(); 31 | 32 | 33 | class wechatCallbackapiTest { 34 | public function responseMsg() { 35 | # 获得数据包的信息 36 | $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; 37 | 38 | # 如果数据包内的信息不为空 39 | if (!empty($postStr)){ 40 | # XML文件的解析依赖libxml库,libxml_disable_entity_loader函数,是为了安全性,防止入侵者通过协议注入XML向服务器发起攻击 41 | libxml_disable_entity_loader(true); 42 | # 把XML编译成一个Class 43 | $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); 44 | # FromUserName : 发送方帐号(一个OpenID) 45 | $fromUsername = $postObj->FromUserName; 46 | # toUsername : 开发者微信号 47 | $toUsername = $postObj->ToUserName; 48 | # keyword : 发送过来的内容 49 | $keyword = trim($postObj->Content); 50 | # 服务器时间戳 51 | $time = time(); 52 | # 这里的XML格式不能改变,是微信规定的格式,里面的参数使用[%s]占位符占用,到时候填充完成,再发送回给微信 53 | $textTpl = " 54 | 55 | 56 | %s 57 | 58 | 59 | 0 60 | "; 61 | # 如果发送过来的内容不为空 62 | if(!empty( $keyword )){ 63 | $APPID = ''; //APPID 64 | $URL = urlencode('http://www.junphp.com/oauth2.php'); //回调地址 65 | $SCOPEN= 'snsapi_userinfo';//两种模式之一 66 | $contentStr = "OAuth2.0网页授权演示 点击这里体验超级黄牛";//这里的参数位置顺序不能改变,点击这个链接就能通过回调获得CODE值 67 | $msgType = "text"; 68 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr); 69 | # 填充完成之后,输出回给微信 70 | echo $resultStr; 71 | } 72 | 73 | } 74 | } 75 | 76 | } 77 | 78 | 79 | -------------------------------------------------------------------------------- /2、微信自动回复(文字).php: -------------------------------------------------------------------------------- 1 | 基本配置 -> 服务器配置中填写的Token令牌值 14 | define("TOKEN", "weixin"); 15 | # 实例化示例类 16 | $wechatObj = new wechatCallbackapiTest(); 17 | # 由于数字认证已经通过,valid()与checkSignature()方法删除掉,没有作用了 18 | # 只需要留下responseMsg方法,作为回调方法 19 | $wechatObj->responseMsg(); 20 | 21 | 22 | class wechatCallbackapiTest { 23 | // 第一次绑定服务器地址的时候,用不到这个方法 24 | public function responseMsg() { 25 | # 获得数据包的信息 26 | $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; 27 | 28 | # 如果数据包内的信息不为空 29 | if (!empty($postStr)){ 30 | # XML文件的解析依赖libxml库,libxml_disable_entity_loader函数,是为了安全性,防止入侵者通过协议注入XML向服务器发起攻击 31 | libxml_disable_entity_loader(true); 32 | # 把XML编译成一个Class 33 | $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); 34 | # FromUserName : 发送方帐号(一个OpenID) 35 | $fromUsername = $postObj->FromUserName; 36 | # toUsername : 开发者微信号 37 | $toUsername = $postObj->ToUserName; 38 | # keyword : 发送过来的内容 39 | $keyword = trim($postObj->Content); 40 | # 服务器时间戳 41 | $time = time(); 42 | # 这里的XML格式不能改变,是微信规定的格式,里面的参数使用[%s]占位符占用,到时候填充完成,再发送回给微信 43 | $textTpl = " 44 | 45 | 46 | %s 47 | 48 | 49 | 0 50 | "; 51 | # 如果发送过来的内容不为空 52 | if(!empty( $keyword )){ 53 | 54 | # $contentStr 是要返回给微信显示的内容 55 | switch ($keyword) { 56 | case '时间': 57 | $contentStr = date('Y-m-d H:i:s',time()); 58 | break; 59 | case '你好': 60 | $contentStr = 'Hello Jun!'; 61 | break; 62 | default: 63 | $contentStr = '没找到相关的自动回复内容!'; 64 | } 65 | 66 | # 返回给微信的字符串类型 - 具体有哪些类型可以在 微信后台 -> 开发者手册 -> 消息管理 第一章中看到 67 | # text 是文本类型 68 | $msgType = "text"; 69 | /** 70 | * ---------这里有些重要---------- 71 | * 使用sprintf 向上面的$textTpl填充变量 72 | * ToUserName = $fromUsername 73 | * FromUserName = $toUsername 74 | * …… 75 | * 对应顺序位置 76 | */ 77 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr); 78 | # 填充完成之后,输出回给微信 79 | echo $resultStr; 80 | }else{ 81 | echo "Input something..."; 82 | } 83 | 84 | }else { 85 | echo ""; 86 | exit; 87 | } 88 | } 89 | 90 | } -------------------------------------------------------------------------------- /16、PHP微信开发 生成短链接.php: -------------------------------------------------------------------------------- 1 | GetToken()); 19 | $WeiXin = new WeiXin(); 20 | $WeiXin->Url(); 21 | 22 | class WeiXin{ 23 | public function Url(){ 24 | # 接口地址 25 | $url = 'https://api.weixin.qq.com/cgi-bin/shorturl?access_token='.ACCESS_TOKEN; 26 | # 参数 27 | $data= array( 28 | 'action' => 'long2short',//必填改字符串 29 | 'long_url' => 'http://www.junphp.com/Blog/index.php',//需要转换的链接 30 | ); 31 | $result = self::https_request($url, json_encode($data));//一定要转成JSON 32 | $res = json_decode($result,true); 33 | $this->Error_Log(array( 34 | '接口地址' => $url, 35 | '错误码' => $res['errcode'], 36 | '错误消息' => $res['errmsg'], 37 | '短链接' => $res['short_url'] 38 | ));//记录日志,以防报错 39 | } 40 | 41 | # 作者:焰哥 - 用于微信接口数据传输的万能函数 42 | private static function https_request($url, $data = null){ 43 | # 初始化一个cURL会话 44 | $curl = curl_init(); 45 | 46 | //设置请求选项, 包括具体的url 47 | curl_setopt($curl, CURLOPT_URL, $url); 48 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); //禁用后cURL将终止从服务端进行验证 49 | curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 50 | 51 | if (!empty($data)){ 52 | curl_setopt($curl, CURLOPT_POST, 1); //设置为post请求类型 53 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data); //设置具体的post数据 54 | } 55 | 56 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 57 | $response = curl_exec($curl); //执行一个cURL会话并且获取相关回复 58 | curl_close($curl); //释放cURL句柄,关闭一个cURL会话 59 | 60 | return $response; 61 | } 62 | 63 | /** 64 | * @Title : 记录错误信息与查看部分信息 65 | * @Author : 小黄牛 66 | * @param array : $Arr_Title 一个一维数组自定义内容 67 | * @param bool : $Arr_Error 是否插入系统错误信息 68 | * @param string : $File 日志名 69 | * @return : 无 70 | */ 71 | private function Error_Log($Arr_Title,$Arr_Error=false,$File='Error_log.log'){ 72 | # 不是数组中断程序 73 | if (!is_array($Arr_Title)) {return false;} 74 | # 定义一个空的变量,用于存放日志TXT实体 75 | $Error_TXT = "自定义信息如下:\r\n"; 76 | # 解析Arr_Title 自定义日志内容 77 | foreach ($Arr_Title as $key=>$val){ 78 | $Error_TXT .= $key.':'.$val."\r\n"; 79 | } 80 | 81 | # 判断系统错误显示是否开启 82 | if ($Arr_Error === true) { 83 | # 获取刚发生的错误信息,并返回数组,无错返回null 84 | $Arr_Error = error_get_last(); 85 | # 不为空则执行错误解析 86 | if (isset($Arr_Error)) { 87 | $Error_TXT .= "系统错误信息如下:\r\n"; 88 | # 解析$Arr_Errore 系统错误信息 89 | foreach ($Arr_Title as $key=>$val){ 90 | $Error_TXT .= $key.':'.$val."\r\n"; 91 | } 92 | } 93 | } 94 | 95 | # 最后再写入两个换行符,以便追加查看 96 | $Error_TXT .= "\r\n\r\n"; 97 | # 最后写入日志 98 | error_log($Error_TXT,3,$File); 99 | } 100 | } 101 | 102 | -------------------------------------------------------------------------------- /11、PHP微信开发之通过CODE参数获取用户信息.php: -------------------------------------------------------------------------------- 1 | responseMsg(); 16 | 17 | class wechatCallbackapiTest { 18 | 19 | public function responseMsg() { 20 | $APPID = '';//APPID 21 | $SECRET = '';//APP SECRET 22 | $CODE = '';//CODE 23 | # 用code去换取网页Access_Token 24 | $URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=$APPID&secret=$SECRET&code=$CODE&grant_type=authorization_code"; 25 | $request= self::https_request($URL); 26 | $this->Error_Log(array('换取到的TOKEN信息:',$request)); 27 | 28 | # 用access_token和openid去换取用户信息 29 | $res = json_decode($request,true); 30 | $access_token = $res['access_token']; 31 | $openid = $res['openid']; 32 | $URL = "https://api.weixin.qq.com/sns/userinfo?access_token=$access_token&openid=$openid"; 33 | $request= self::https_request($URL); 34 | $this->Error_Log(array('换取到的用户信息:',$request)); 35 | } 36 | 37 | # 作者:焰哥 - 用于微信接口数据传输的万能函数 38 | private static function https_request($url, $data = null){ 39 | # 初始化一个cURL会话 40 | $curl = curl_init(); 41 | 42 | //设置请求选项, 包括具体的url 43 | curl_setopt($curl, CURLOPT_URL, $url); 44 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); //禁用后cURL将终止从服务端进行验证 45 | curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 46 | 47 | if (!empty($data)){ 48 | curl_setopt($curl, CURLOPT_POST, 1); //设置为post请求类型 49 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data); //设置具体的post数据 50 | } 51 | 52 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 53 | $response = curl_exec($curl); //执行一个cURL会话并且获取相关回复 54 | curl_close($curl); //释放cURL句柄,关闭一个cURL会话 55 | 56 | return $response; 57 | } 58 | 59 | /** 60 | * @Title : 记录错误信息与查看部分信息 61 | * @Author : 小黄牛 62 | * @param array : $Arr_Title 一个一维数组自定义内容 63 | * @param bool : $Arr_Error 是否插入系统错误信息 64 | * @param string : $File 日志名 65 | * @return : 无 66 | */ 67 | private function Error_Log($Arr_Title,$Arr_Error=false,$File='Error_log.log'){ 68 | # 不是数组中断程序 69 | if (!is_array($Arr_Title)) {return false;} 70 | # 定义一个空的变量,用于存放日志TXT实体 71 | $Error_TXT = "自定义信息如下:\r\n"; 72 | # 解析Arr_Title 自定义日志内容 73 | foreach ($Arr_Title as $key=>$val){ 74 | $Error_TXT .= $key.':'.$val."\r\n"; 75 | } 76 | 77 | # 判断系统错误显示是否开启 78 | if ($Arr_Error === true) { 79 | # 获取刚发生的错误信息,并返回数组,无错返回null 80 | $Arr_Error = error_get_last(); 81 | # 不为空则执行错误解析 82 | if (isset($Arr_Error)) { 83 | $Error_TXT .= "系统错误信息如下:\r\n"; 84 | # 解析$Arr_Errore 系统错误信息 85 | foreach ($Arr_Title as $key=>$val){ 86 | $Error_TXT .= $key.':'.$val."\r\n"; 87 | } 88 | } 89 | } 90 | 91 | # 最后再写入两个换行符,以便追加查看 92 | $Error_TXT .= "\r\n\r\n"; 93 | # 最后写入日志 94 | error_log($Error_TXT,3,$File); 95 | } 96 | 97 | } 98 | 99 | /** 100 | * 最后分享下在微网站开发中,获取code的心得(我也是在Q群朋友的帮助下学会的) 101 | * 将oauth2.0认证页面设置在index.php,获取openid写入cookie 102 | * 根据openid去数据库查找会员信息,没有则新建会员 103 | * 其实这个作用,就是微网站的会员默认登录注册作用 104 | */ -------------------------------------------------------------------------------- /3、微信自动回复(图文).php: -------------------------------------------------------------------------------- 1 | 基本配置 -> 服务器配置中填写的Token令牌值 14 | define("TOKEN", "weixin"); 15 | # 实例化示例类 16 | $wechatObj = new wechatCallbackapiTest(); 17 | # 由于数字认证已经通过,valid()与checkSignature()方法删除掉,没有作用了 18 | # 只需要留下responseMsg方法,作为回调方法 19 | $wechatObj->responseMsg(); 20 | 21 | 22 | class wechatCallbackapiTest { 23 | // 第一次绑定服务器地址的时候,用不到这个方法 24 | public function responseMsg() { 25 | # 获得数据包的信息 26 | $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; 27 | 28 | # 如果数据包内的信息不为空 29 | if (!empty($postStr)){ 30 | # XML文件的解析依赖libxml库,libxml_disable_entity_loader函数,是为了安全性,防止入侵者通过协议注入XML向服务器发起攻击 31 | libxml_disable_entity_loader(true); 32 | # 把XML编译成一个Class 33 | $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); 34 | # FromUserName : 发送方帐号(一个OpenID) 35 | $fromUsername = $postObj->FromUserName; 36 | # toUsername : 开发者微信号 37 | $toUsername = $postObj->ToUserName; 38 | # keyword : 发送过来的内容 39 | $keyword = trim($postObj->Content); 40 | # 服务器时间戳 41 | $time = time(); 42 | # 这里的XML格式不能改变,是微信规定的格式,里面的参数使用[%s]占位符占用,到时候填充完成,再发送回给微信 43 | $textTpl=" 44 | 45 | 46 | %s 47 | 48 | 1 49 | 50 | 51 | <![CDATA[%s]]> 52 | 53 | 54 | 55 | 56 | 57 | "; 58 | 59 | # 如果发送过来的内容不为空 60 | if(!empty( $keyword )){ 61 | # 返回给微信的字符串类型 - 具体有哪些类型可以在 微信后台 -> 开发者手册 -> 消息管理 第一章中看到 62 | # news 是图文类型 63 | $msgType = "news"; 64 | # 图文的标题 65 | $titleStr = "这是一个图文消息回复"; 66 | # 图文的body描述 67 | $contentStr = "你点击后将跳转到Jun的博客"; 68 | # 图文显示的图片 69 | $imgStr = "http://www.im158.com/weixin/1.png"; 70 | # 图片点击的链接地址 71 | $urlStr = "http://www.junphp.com/Blog/"; 72 | /** 73 | * ---------这里有些重要---------- 74 | * 使用sprintf 向上面的$textTpl填充变量 75 | * ToUserName = $fromUsername 76 | * FromUserName = $toUsername 77 | * …… 78 | * 对应顺序位置 79 | */ 80 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $titleStr, $contentStr, $imgStr, $urlStr); 81 | # 填充完成之后,输出回给微信 82 | echo $resultStr; 83 | }else{ 84 | echo "Input something..."; 85 | } 86 | 87 | }else { 88 | echo ""; 89 | exit; 90 | } 91 | } 92 | 93 | 94 | } -------------------------------------------------------------------------------- /15、PHP微信开发 扫描二维码推送事件.php: -------------------------------------------------------------------------------- 1 | qrscene_ 为前缀,后面为二维码的参数值 17 | + 二维码的ticket 18 | + 19 | + 20 | + 用户已关注时的事件推送 21 | + 开发者的微信公众号 22 | + 发送者的Openid 23 | + 时间戳 24 | + 消息类型 event 25 | + 事件类型 SCAN 26 | + 创建二维码时的scene_id 27 | + 二维码的ticket 28 | +---------------------------------------------------------------------------------------------------------------------------------------------- 29 | */ 30 | 31 | # 实例化示例类 32 | $wechatObj = new wechatCallbackapiTest(); 33 | # 由于数字认证已经通过,valid()与checkSignature()方法删除掉,没有作用了 34 | # 只需要留下responseMsg方法,作为回调方法 35 | $wechatObj->responseMsg(); 36 | 37 | 38 | class wechatCallbackapiTest { 39 | 40 | public function responseMsg() { 41 | # 获得数据包的信息 42 | $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; 43 | 44 | # 如果数据包内的信息不为空 45 | if (!empty($postStr)){ 46 | # XML文件的解析依赖libxml库,libxml_disable_entity_loader函数,是为了安全性,防止入侵者通过协议注入XML向服务器发起攻击 47 | libxml_disable_entity_loader(true); 48 | # 把XML编译成一个Class 49 | $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); 50 | # rx_type : 请求类型 51 | $rx_type = trim($postObj->MsgType); 52 | # rx_event : 操作的事件 53 | $rx_event = $postObj->Event; 54 | 55 | switch ($rx_event){ 56 | # 关注 57 | case 'SUBSCRIBE': 58 | # 调用日志记录-方便出错则查看 59 | $this->Error_Log(array( 60 | '类型' => '成功关注' 61 | )); 62 | break; 63 | # 扫描二维码事件 64 | case 'SCAN': 65 | # 调用日志记录-方便出错则查看 66 | $this->Error_Log(array( 67 | '类型' => $rx_event, 68 | 'scene_id' => $postObj->EventKey 69 | ),false); 70 | break; 71 | } 72 | 73 | } 74 | } 75 | 76 | /** 77 | * @Title : 记录错误信息与查看部分信息 78 | * @Author : 小黄牛 79 | * @param array : $Arr_Title 一个一维数组自定义内容 80 | * @param bool : $Arr_Error 是否插入系统错误信息 81 | * @param string : $File 日志名 82 | * @return : 无 83 | */ 84 | private function Error_Log($Arr_Title,$Arr_Error=false,$File='Error_log.log'){ 85 | # 不是数组中断程序 86 | if (!is_array($Arr_Title)) {return false;} 87 | # 定义一个空的变量,用于存放日志TXT实体 88 | $Error_TXT = "自定义信息如下:\r\n"; 89 | # 解析Arr_Title 自定义日志内容 90 | foreach ($Arr_Title as $key=>$val){ 91 | $Error_TXT .= $key.':'.$val."\r\n"; 92 | } 93 | 94 | # 判断系统错误显示是否开启 95 | if ($Arr_Error === true) { 96 | # 获取刚发生的错误信息,并返回数组,无错返回null 97 | $Arr_Error = error_get_last(); 98 | # 不为空则执行错误解析 99 | if (isset($Arr_Error)) { 100 | $Error_TXT .= "系统错误信息如下:\r\n"; 101 | # 解析$Arr_Errore 系统错误信息 102 | foreach ($Arr_Title as $key=>$val){ 103 | $Error_TXT .= $key.':'.$val."\r\n"; 104 | } 105 | } 106 | } 107 | 108 | # 最后再写入两个换行符,以便追加查看 109 | $Error_TXT .= "\r\n\r\n"; 110 | # 最后写入日志 111 | error_log($Error_TXT,3,$File); 112 | } 113 | } -------------------------------------------------------------------------------- /17、PHP微信开发 上传临时素材.php: -------------------------------------------------------------------------------- 1 | GetToken()); 27 | $WeiXin = new WeiXin(); 28 | $WeiXin->Url(); 29 | 30 | class WeiXin{ 31 | public function Url(){ 32 | # 上传类型 33 | $type = 'image';//媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb) 34 | # 接口地址 35 | $url = 'https://api.weixin.qq.com/cgi-bin/media/upload?access_token='.ACCESS_TOKEN.'&type='.$type; 36 | # 参数 37 | $data= array( 38 | 'media' => '@'.'1.jpg',//前头必须带个@ 39 | ); 40 | $result = self::https_request($url, $data);//一定要转成JSON 41 | $res = json_decode($result,true); 42 | $this->Error_Log(array( 43 | '接口地址' => $url, 44 | '图片类型' => $res['type'], 45 | '唯一标识' => $res['media_id'], 46 | '上传时间' => $res['created_at'] 47 | ));//记录日志,以防报错 48 | } 49 | 50 | # 作者:焰哥 - 用于微信接口数据传输的万能函数 51 | private static function https_request($url, $data = null){ 52 | # 初始化一个cURL会话 53 | $curl = curl_init(); 54 | 55 | //设置请求选项, 包括具体的url 56 | curl_setopt($curl, CURLOPT_URL, $url); 57 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); //禁用后cURL将终止从服务端进行验证 58 | curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 59 | 60 | if (!empty($data)){ 61 | curl_setopt($curl, CURLOPT_POST, 1); //设置为post请求类型 62 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data); //设置具体的post数据 63 | } 64 | 65 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 66 | $response = curl_exec($curl); //执行一个cURL会话并且获取相关回复 67 | curl_close($curl); //释放cURL句柄,关闭一个cURL会话 68 | 69 | return $response; 70 | } 71 | 72 | /** 73 | * @Title : 记录错误信息与查看部分信息 74 | * @Author : 小黄牛 75 | * @param array : $Arr_Title 一个一维数组自定义内容 76 | * @param bool : $Arr_Error 是否插入系统错误信息 77 | * @param string : $File 日志名 78 | * @return : 无 79 | */ 80 | private function Error_Log($Arr_Title,$Arr_Error=false,$File='Error_log.log'){ 81 | # 不是数组中断程序 82 | if (!is_array($Arr_Title)) {return false;} 83 | # 定义一个空的变量,用于存放日志TXT实体 84 | $Error_TXT = "自定义信息如下:\r\n"; 85 | # 解析Arr_Title 自定义日志内容 86 | foreach ($Arr_Title as $key=>$val){ 87 | $Error_TXT .= $key.':'.$val."\r\n"; 88 | } 89 | 90 | # 判断系统错误显示是否开启 91 | if ($Arr_Error === true) { 92 | # 获取刚发生的错误信息,并返回数组,无错返回null 93 | $Arr_Error = error_get_last(); 94 | # 不为空则执行错误解析 95 | if (isset($Arr_Error)) { 96 | $Error_TXT .= "系统错误信息如下:\r\n"; 97 | # 解析$Arr_Errore 系统错误信息 98 | foreach ($Arr_Title as $key=>$val){ 99 | $Error_TXT .= $key.':'.$val."\r\n"; 100 | } 101 | } 102 | } 103 | 104 | # 最后再写入两个换行符,以便追加查看 105 | $Error_TXT .= "\r\n\r\n"; 106 | # 最后写入日志 107 | error_log($Error_TXT,3,$File); 108 | } 109 | } 110 | 111 | -------------------------------------------------------------------------------- /18、PHP微信开发 上传永久素材.php: -------------------------------------------------------------------------------- 1 | GetToken()); 26 | $WeiXin = new WeiXin(); 27 | $WeiXin->Url(); 28 | 29 | class WeiXin{ 30 | public function Url(){ 31 | # 上传类型 32 | $type = 'image';//媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb) 33 | # 接口地址 - 这里只是图片的接口,其他类型参照官方手册 34 | $url = 'https://api.weixin.qq.com/cgi-bin/material/add_material?access_token='.ACCESS_TOKEN; 35 | # 参数 36 | $data= array( 37 | 'type' => $type, 38 | 'media' => '@'.'1.jpg',//前头必须带个@ 39 | ); 40 | $result = self::https_request($url, $data);//一定要转成JSON 41 | $this->Error_Log(array( 42 | 'JSON' => $result 43 | ));//记录日志,以防报错 44 | $res = json_decode($result,true); 45 | $this->Error_Log(array( 46 | '接口地址' => $url, 47 | '唯一标识' => $res['media_id'], 48 | '图片地址' => $res['url'] 49 | ));//记录日志,以防报错 50 | } 51 | 52 | # 作者:焰哥 - 用于微信接口数据传输的万能函数 53 | private static function https_request($url, $data = null){ 54 | # 初始化一个cURL会话 55 | $curl = curl_init(); 56 | 57 | //设置请求选项, 包括具体的url 58 | curl_setopt($curl, CURLOPT_URL, $url); 59 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); //禁用后cURL将终止从服务端进行验证 60 | curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 61 | 62 | if (!empty($data)){ 63 | curl_setopt($curl, CURLOPT_POST, 1); //设置为post请求类型 64 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data); //设置具体的post数据 65 | } 66 | 67 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 68 | $response = curl_exec($curl); //执行一个cURL会话并且获取相关回复 69 | curl_close($curl); //释放cURL句柄,关闭一个cURL会话 70 | 71 | return $response; 72 | } 73 | 74 | /** 75 | * @Title : 记录错误信息与查看部分信息 76 | * @Author : 小黄牛 77 | * @param array : $Arr_Title 一个一维数组自定义内容 78 | * @param bool : $Arr_Error 是否插入系统错误信息 79 | * @param string : $File 日志名 80 | * @return : 无 81 | */ 82 | private function Error_Log($Arr_Title,$Arr_Error=false,$File='Error_log.log'){ 83 | # 不是数组中断程序 84 | if (!is_array($Arr_Title)) {return false;} 85 | # 定义一个空的变量,用于存放日志TXT实体 86 | $Error_TXT = "自定义信息如下:\r\n"; 87 | # 解析Arr_Title 自定义日志内容 88 | foreach ($Arr_Title as $key=>$val){ 89 | $Error_TXT .= $key.':'.$val."\r\n"; 90 | } 91 | 92 | # 判断系统错误显示是否开启 93 | if ($Arr_Error === true) { 94 | # 获取刚发生的错误信息,并返回数组,无错返回null 95 | $Arr_Error = error_get_last(); 96 | # 不为空则执行错误解析 97 | if (isset($Arr_Error)) { 98 | $Error_TXT .= "系统错误信息如下:\r\n"; 99 | # 解析$Arr_Errore 系统错误信息 100 | foreach ($Arr_Title as $key=>$val){ 101 | $Error_TXT .= $key.':'.$val."\r\n"; 102 | } 103 | } 104 | } 105 | 106 | # 最后再写入两个换行符,以便追加查看 107 | $Error_TXT .= "\r\n\r\n"; 108 | # 最后写入日志 109 | error_log($Error_TXT,3,$File); 110 | } 111 | } 112 | 113 | -------------------------------------------------------------------------------- /9、PHP微信开发 获取用户信息之关注时获取.php: -------------------------------------------------------------------------------- 1 | GetToken()); 19 | $Test = new wechatCallbackapiTest(); 20 | $Test->responseMsg(); 21 | 22 | class wechatCallbackapiTest { 23 | // 第一次绑定服务器地址的时候,用不到这个方法 24 | public function responseMsg() { 25 | # 获得数据包的信息 26 | $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; 27 | 28 | # 如果数据包内的信息不为空 29 | if (!empty($postStr)){ 30 | # XML文件的解析依赖libxml库,libxml_disable_entity_loader函数,是为了安全性,防止入侵者通过协议注入XML向服务器发起攻击 31 | libxml_disable_entity_loader(true); 32 | # 把XML编译成一个Class 33 | $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); 34 | # FromUserName : 发送方帐号(一个OpenID) 35 | $fromUsername = $postObj->FromUserName; 36 | 37 | #FromUserName 是用户的 OpenID 38 | $url = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token='.ACCESS_TOKEN.'&openid='.$fromUsername; 39 | # 用户信息请求接口 40 | $info = self::https_request($url); 41 | $array = array('用户信息',$info); 42 | # 写入文件,用户信息不能让人看见啊..... 43 | $this->Error_Log($array); 44 | 45 | } 46 | } 47 | 48 | # 作者:焰哥 - 用于微信接口数据传输的万能函数 49 | private static function https_request($url, $data = null){ 50 | # 初始化一个cURL会话 51 | $curl = curl_init(); 52 | 53 | //设置请求选项, 包括具体的url 54 | curl_setopt($curl, CURLOPT_URL, $url); 55 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); //禁用后cURL将终止从服务端进行验证 56 | curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 57 | 58 | if (!empty($data)){ 59 | curl_setopt($curl, CURLOPT_POST, 1); //设置为post请求类型 60 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data); //设置具体的post数据 61 | } 62 | 63 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 64 | $response = curl_exec($curl); //执行一个cURL会话并且获取相关回复 65 | curl_close($curl); //释放cURL句柄,关闭一个cURL会话 66 | 67 | return $response; 68 | } 69 | 70 | /** 71 | * @Title : 记录错误信息与查看部分信息 72 | * @Author : 小黄牛 73 | * @param array : $Arr_Title 一个一维数组自定义内容 74 | * @param bool : $Arr_Error 是否插入系统错误信息 75 | * @param string : $File 日志名 76 | * @return : 无 77 | */ 78 | private function Error_Log($Arr_Title,$Arr_Error=false,$File='Error_log.log'){ 79 | # 不是数组中断程序 80 | if (!is_array($Arr_Title)) {return false;} 81 | # 定义一个空的变量,用于存放日志TXT实体 82 | $Error_TXT = "自定义信息如下:\r\n"; 83 | # 解析Arr_Title 自定义日志内容 84 | foreach ($Arr_Title as $key=>$val){ 85 | $Error_TXT .= $key.':'.$val."\r\n"; 86 | } 87 | 88 | # 判断系统错误显示是否开启 89 | if ($Arr_Error === true) { 90 | # 获取刚发生的错误信息,并返回数组,无错返回null 91 | $Arr_Error = error_get_last(); 92 | # 不为空则执行错误解析 93 | if (isset($Arr_Error)) { 94 | $Error_TXT .= "系统错误信息如下:\r\n"; 95 | # 解析$Arr_Errore 系统错误信息 96 | foreach ($Arr_Title as $key=>$val){ 97 | $Error_TXT .= $key.':'.$val."\r\n"; 98 | } 99 | } 100 | } 101 | 102 | # 最后再写入两个换行符,以便追加查看 103 | $Error_TXT .= "\r\n\r\n"; 104 | # 最后写入日志 105 | error_log($Error_TXT,3,$File); 106 | } 107 | 108 | } 109 | 110 | 111 | -------------------------------------------------------------------------------- /14、PHP微信开发 生成带参数的二维码 - 永久版.php: -------------------------------------------------------------------------------- 1 | GetToken()); 29 | $WeiXin = new WeiXin(); 30 | $WeiXin->Temporary_QR(); 31 | 32 | class WeiXin{ 33 | # 生成永久二维码 34 | public function Temporary_QR(){ 35 | # 请求这个连接获得ticket 36 | $url = 'https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token='.ACCESS_TOKEN; 37 | # 设置二维码参数 38 | $data = array( 39 | 'action_name' => 'QR_LIMIT_SCENE',//二维码类型,QR_LIMIT_SCENE为永久 40 | # 场景参数 41 | 'action_info' => array( 42 | 'scene' => array( 43 | 'scene_id' => 456 // 场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000) 44 | ) 45 | ) 46 | ); 47 | $result = self::https_request($url,json_encode($data));//参数一定要转成JSON 48 | $this->Error_Log(array('ticket参数'=>$result),true);//记录日志,以防报错 49 | $res = json_decode($result,true); 50 | # $ticket存在数据库 ,要显示的时候访问下面的地址 51 | $ticket = $res['ticket']; 52 | 53 | # 使用ticket请求这个链接,获得二维码 54 | $url = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket='.urlencode($ticket); 55 | $img = self::https_request($url); 56 | # 查看二维码 57 | echo ""; 58 | } 59 | 60 | # 作者:焰哥 - 用于微信接口数据传输的万能函数 61 | private static function https_request($url, $data = null){ 62 | # 初始化一个cURL会话 63 | $curl = curl_init(); 64 | 65 | //设置请求选项, 包括具体的url 66 | curl_setopt($curl, CURLOPT_URL, $url); 67 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); //禁用后cURL将终止从服务端进行验证 68 | curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 69 | 70 | if (!empty($data)){ 71 | curl_setopt($curl, CURLOPT_POST, 1); //设置为post请求类型 72 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data); //设置具体的post数据 73 | } 74 | 75 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 76 | $response = curl_exec($curl); //执行一个cURL会话并且获取相关回复 77 | curl_close($curl); //释放cURL句柄,关闭一个cURL会话 78 | 79 | return $response; 80 | } 81 | 82 | /** 83 | * @Title : 记录错误信息与查看部分信息 84 | * @Author : 小黄牛 85 | * @param array : $Arr_Title 一个一维数组自定义内容 86 | * @param bool : $Arr_Error 是否插入系统错误信息 87 | * @param string : $File 日志名 88 | * @return : 无 89 | */ 90 | private function Error_Log($Arr_Title,$Arr_Error=false,$File='Error_log.log'){ 91 | # 不是数组中断程序 92 | if (!is_array($Arr_Title)) {return false;} 93 | # 定义一个空的变量,用于存放日志TXT实体 94 | $Error_TXT = "自定义信息如下:\r\n"; 95 | # 解析Arr_Title 自定义日志内容 96 | foreach ($Arr_Title as $key=>$val){ 97 | $Error_TXT .= $key.':'.$val."\r\n"; 98 | } 99 | 100 | # 判断系统错误显示是否开启 101 | if ($Arr_Error === true) { 102 | # 获取刚发生的错误信息,并返回数组,无错返回null 103 | $Arr_Error = error_get_last(); 104 | # 不为空则执行错误解析 105 | if (isset($Arr_Error)) { 106 | $Error_TXT .= "系统错误信息如下:\r\n"; 107 | # 解析$Arr_Errore 系统错误信息 108 | foreach ($Arr_Title as $key=>$val){ 109 | $Error_TXT .= $key.':'.$val."\r\n"; 110 | } 111 | } 112 | } 113 | 114 | # 最后再写入两个换行符,以便追加查看 115 | $Error_TXT .= "\r\n\r\n"; 116 | # 最后写入日志 117 | error_log($Error_TXT,3,$File); 118 | } 119 | } 120 | 121 | -------------------------------------------------------------------------------- /13、PHP微信开发 生成带参数的二维码 - 临时版.php: -------------------------------------------------------------------------------- 1 | GetToken()); 29 | $WeiXin = new WeiXin(); 30 | $WeiXin->Temporary_QR(); 31 | 32 | class WeiXin{ 33 | # 生成临时二维码 34 | public function Temporary_QR(){ 35 | # 请求这个连接获得ticket 36 | $url = 'https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token='.ACCESS_TOKEN; 37 | # 设置二维码参数 38 | $data = array( 39 | 'expire_seconds' => 2592000,//有效时间,秒 40 | 'action_name' => 'QR_SCENE',//二维码类型,QR_SCENE为临时 41 | # 场景参数 42 | 'action_info' => array( 43 | 'scene' => array( 44 | 'scene_id' => 123 // 场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000) 45 | ) 46 | ) 47 | ); 48 | $result = self::https_request($url,json_encode($data));//参数一定要转成JSON 49 | $this->Error_Log(array('ticket参数'=>$result));//记录日志,以防报错 50 | $res = json_decode($result,true); 51 | # $ticket存在数据库 ,要显示的时候访问下面的地址 52 | $ticket = $res['ticket']; 53 | 54 | # 使用ticket请求这个链接,获得二维码 55 | $url = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket='.urlencode($ticket); 56 | $img = self::https_request($url); 57 | # 查看二维码 58 | echo ""; 59 | } 60 | 61 | # 作者:焰哥 - 用于微信接口数据传输的万能函数 62 | private static function https_request($url, $data = null){ 63 | # 初始化一个cURL会话 64 | $curl = curl_init(); 65 | 66 | //设置请求选项, 包括具体的url 67 | curl_setopt($curl, CURLOPT_URL, $url); 68 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); //禁用后cURL将终止从服务端进行验证 69 | curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 70 | 71 | if (!empty($data)){ 72 | curl_setopt($curl, CURLOPT_POST, 1); //设置为post请求类型 73 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data); //设置具体的post数据 74 | } 75 | 76 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 77 | $response = curl_exec($curl); //执行一个cURL会话并且获取相关回复 78 | curl_close($curl); //释放cURL句柄,关闭一个cURL会话 79 | 80 | return $response; 81 | } 82 | 83 | /** 84 | * @Title : 记录错误信息与查看部分信息 85 | * @Author : 小黄牛 86 | * @param array : $Arr_Title 一个一维数组自定义内容 87 | * @param bool : $Arr_Error 是否插入系统错误信息 88 | * @param string : $File 日志名 89 | * @return : 无 90 | */ 91 | private function Error_Log($Arr_Title,$Arr_Error=false,$File='Error_log.log'){ 92 | # 不是数组中断程序 93 | if (!is_array($Arr_Title)) {return false;} 94 | # 定义一个空的变量,用于存放日志TXT实体 95 | $Error_TXT = "自定义信息如下:\r\n"; 96 | # 解析Arr_Title 自定义日志内容 97 | foreach ($Arr_Title as $key=>$val){ 98 | $Error_TXT .= $key.':'.$val."\r\n"; 99 | } 100 | 101 | # 判断系统错误显示是否开启 102 | if ($Arr_Error === true) { 103 | # 获取刚发生的错误信息,并返回数组,无错返回null 104 | $Arr_Error = error_get_last(); 105 | # 不为空则执行错误解析 106 | if (isset($Arr_Error)) { 107 | $Error_TXT .= "系统错误信息如下:\r\n"; 108 | # 解析$Arr_Errore 系统错误信息 109 | foreach ($Arr_Title as $key=>$val){ 110 | $Error_TXT .= $key.':'.$val."\r\n"; 111 | } 112 | } 113 | } 114 | 115 | # 最后再写入两个换行符,以便追加查看 116 | $Error_TXT .= "\r\n\r\n"; 117 | # 最后写入日志 118 | error_log($Error_TXT,3,$File); 119 | } 120 | } 121 | 122 | -------------------------------------------------------------------------------- /1、微信接入示例代码解说.php: -------------------------------------------------------------------------------- 1 | 基本配置 -> 服务器配置中填写的Token令牌值 14 | define("TOKEN", "weixin"); 15 | # 实例化示例类 16 | $wechatObj = new wechatCallbackapiTest(); 17 | # 调用API数字认证方法 - 第一次绑定服务器地址的时候用到,绑定成功之后就不需要再用了 18 | $wechatObj->valid(); 19 | 20 | 21 | class wechatCallbackapiTest { 22 | 23 | // 处理数字验证,并返回认证结果给微信 24 | public function valid(){ 25 | # 接收微信向你服务器发送过来的随机字符串 26 | $echoStr = $_GET["echostr"]; 27 | # 执行checkSignature , 进行数字认证 28 | if($this->checkSignature()){ 29 | # 认证通过返回随机字符串给微信,告诉它认证通过了 30 | echo $echoStr; 31 | exit; 32 | } 33 | } 34 | 35 | // 第一次绑定服务器地址的时候,用不到这个方法 36 | public function responseMsg() { 37 | # 获得数据包的信息 38 | $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; 39 | 40 | # 如果数据包内的信息不为空 41 | if (!empty($postStr)){ 42 | # XML文件的解析依赖libxml库,libxml_disable_entity_loader函数,是为了安全性,防止入侵者通过协议注入XML向服务器发起攻击 43 | libxml_disable_entity_loader(true); 44 | # 把XML编译成一个Class 45 | $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); 46 | # FromUserName : 发送方帐号(一个OpenID) 47 | $fromUsername = $postObj->FromUserName; 48 | # toUsername : 开发者微信号 49 | $toUsername = $postObj->ToUserName; 50 | # keyword : 发送过来的内容 51 | $keyword = trim($postObj->Content); 52 | # 服务器时间戳 53 | $time = time(); 54 | # 这里的XML格式不能改变,是微信规定的格式,里面的参数使用[%s]占位符占用,到时候填充完成,再发送回给微信 55 | $textTpl = " 56 | 57 | 58 | %s 59 | 60 | 61 | 0 62 | "; 63 | # 如果发送过来的内容不给控 64 | if(!empty( $keyword )){ 65 | # 返回给微信的字符串类型 66 | $msgType = "text"; 67 | # 要返回给微信显示的内容 68 | $contentStr = "Welcome to wechat world!"; 69 | /** 70 | * ---------这里有些重要---------- 71 | * 使用sprintf 向上面的$textTpl填充变量 72 | * ToUserName = $fromUsername 73 | * FromUserName = $toUsername 74 | * …… 75 | * 对应顺序位置 76 | */ 77 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr); 78 | # 填充完成之后,输出回给微信 79 | echo $resultStr; 80 | }else{ 81 | echo "Input something..."; 82 | } 83 | 84 | }else { 85 | echo ""; 86 | exit; 87 | } 88 | } 89 | 90 | // 执行数字验证,只有在第一次绑定服务器地址的时候用到,绑定完就可以删除了 91 | private function checkSignature(){ 92 | # Token令牌 常量没设置,返回错误信息 93 | if (!defined("TOKEN")) { 94 | throw new Exception('TOKEN is not defined!'); 95 | } 96 | # 获得微信发送过来的加密签名 97 | $signature = $_GET["signature"]; 98 | # 时间戳 99 | $timestamp = $_GET["timestamp"]; 100 | # 随机数 101 | $nonce = $_GET["nonce"]; 102 | 103 | # 获得Token令牌 104 | $token = TOKEN; 105 | # Token + 时间戳 + 随机数 = 组合成数组 106 | $tmpArr = array($token, $timestamp, $nonce); 107 | // 对数组进行升序重新排序 108 | sort($tmpArr, SORT_STRING); 109 | # 把数组for拼接成字符串 110 | $tmpStr = implode( $tmpArr ); 111 | # 进行sha1加密 112 | $tmpStr = sha1( $tmpStr ); 113 | 114 | # 最后与微信发送过来的加密签名进行对比,成功返回true 115 | if( $tmpStr == $signature ){ 116 | return true; 117 | }else{ 118 | return false; 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /7、微信Access_Token中控器.php: -------------------------------------------------------------------------------- 1 | GetToken(); 14 | 15 | # 微信获取Access_Token 基础使用类 16 | class Access_Token{ 17 | private static $AppId = '';// 微信的appid 18 | private static $AppSecret = '';// 微信的appsecret 19 | private static $AppToken_Url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s';// 微信获去actoken的地址 20 | private static $AC_Token_Time= 6600;// 单位秒,默认110分钟 21 | # 将Appid与AppSecret植入占位符 22 | private static function StrUrl(){ 23 | $resultStr = sprintf( self::$AppToken_Url, self::$AppId, self::$AppSecret); 24 | return $resultStr; 25 | } 26 | 27 | # 验证access_token有效期,有效则返回最新一条access_token,没则更新 28 | public function GetToken(){ 29 | # 获取最新的一条access_token 30 | $DB = new Model(); 31 | $info = $DB->find('select access_token,token_time from weixin order by id desc'); 32 | # 一条都没有,返回false 33 | if (!$info) {return false;} 34 | # 计算出过期时间 35 | $time = time() + (self::$AC_Token_Time); 36 | # 将过期时间进行对比 - 如果当前时间比库存时间大,则更新Access_Token,否则返回现在的Access_Token 37 | if (time() >= $info['token_time']){ 38 | return self::SaveToken(); 39 | } 40 | return $info['access_token']; 41 | } 42 | 43 | # 更新Access_Token 44 | private static function SaveToken(){ 45 | # 请求TOken 46 | $res = self::https_request(self::StrUrl()); 47 | $result = json_decode($res, true); //接受一个 JSON 格式的字符串并且把它转换为 PHP 变量 48 | $access_token = $result['access_token']; 49 | # 更新一条access_token 50 | $DB = new Model(); 51 | # 计算出过期时间 52 | $time = time() + (self::$AC_Token_Time); 53 | $sql = "INSERT INTO weixin (access_token,token_time) VALUES ('$access_token','$time')"; 54 | $info = $DB->add($sql); 55 | return $access_token; 56 | } 57 | 58 | # 作者:焰哥 - 用于微信接口数据传输的万能函数 59 | private static function https_request($url, $data = null){ 60 | # 初始化一个cURL会话 61 | $curl = curl_init(); 62 | 63 | //设置请求选项, 包括具体的url 64 | curl_setopt($curl, CURLOPT_URL, $url); 65 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); //禁用后cURL将终止从服务端进行验证 66 | curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 67 | 68 | if (!empty($data)){ 69 | curl_setopt($curl, CURLOPT_POST, 1); //设置为post请求类型 70 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data); //设置具体的post数据 71 | } 72 | 73 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 74 | $response = curl_exec($curl); //执行一个cURL会话并且获取相关回复 75 | curl_close($curl); //释放cURL句柄,关闭一个cURL会话 76 | 77 | return $response; 78 | } 79 | 80 | } 81 | 82 | 83 | # PDO类 84 | class Model{ 85 | protected static $dbMs = 'mysql';// 数据库类型 86 | protected static $dbHost = 'localhost';// 数据库主机名 87 | protected static $dbName = '';// 数据库名称 88 | protected static $dbCharset = 'utf8';// 数据库编码 89 | protected static $dbUser = '';// 数据库连接用户名 90 | protected static $dbPwd = '';// 数据库密码 91 | 92 | private $instance;// 数据库PDO连接实例 93 | 94 | # 获得PDO实例 95 | public function __construct(){ $this->dbPdo();} 96 | 97 | # 执行PDO链接 98 | private function dbPdo(){ 99 | $dbn = self::$dbMs.':host='.self::$dbHost.';dbname='.self::$dbName.';charset='.self::$dbCharset; 100 | $dbh = new PDO($dbn,self::$dbUser,self::$dbPwd); 101 | $this->instance = $dbh; 102 | } 103 | 104 | # 执行SELECT查询获取单条记录,返回一维数组 105 | public function find($Sql){ 106 | $pdo = $this->instance; 107 | $res = $pdo->query($Sql); 108 | $res->setFetchMode(PDO::FETCH_ASSOC); //数字索引方式 109 | return $res->fetch(); 110 | } 111 | 112 | # 添加操作 113 | public function add($Sql){ 114 | $pdo = $this->instance; 115 | return $pdo->exec($Sql); 116 | } 117 | } 118 | 119 | 120 | 121 | /** 122 | * 表结构 123 | CREATE TABLE IF NOT EXISTS `weixin` ( 124 | `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', 125 | `access_token` varchar(513) CHARACTER SET utf8 NOT NULL COMMENT 'access_token,最少为512字节,稳妥点存513', 126 | `token_time` varchar(20) CHARACTER SET utf8 NOT NULL COMMENT '过期时间戳为2小时-10分钟', 127 | PRIMARY KEY (`id`) 128 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; 129 | */ -------------------------------------------------------------------------------- /5、微信取消与关注事件.php: -------------------------------------------------------------------------------- 1 | 基本配置 -> 服务器配置中填写的Token令牌值 14 | define("TOKEN", "weixin"); 15 | # 实例化示例类 16 | $wechatObj = new wechatCallbackapiTest(); 17 | # 由于数字认证已经通过,valid()与checkSignature()方法删除掉,没有作用了 18 | # 只需要留下responseMsg方法,作为回调方法 19 | $wechatObj->responseMsg(); 20 | 21 | 22 | class wechatCallbackapiTest { 23 | // 第一次绑定服务器地址的时候,用不到这个方法 24 | public function responseMsg() { 25 | # 获得数据包的信息 26 | $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; 27 | 28 | # 如果数据包内的信息不为空 29 | if (!empty($postStr)){ 30 | # XML文件的解析依赖libxml库,libxml_disable_entity_loader函数,是为了安全性,防止入侵者通过协议注入XML向服务器发起攻击 31 | libxml_disable_entity_loader(true); 32 | # 把XML编译成一个Class 33 | $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); 34 | # FromUserName : 发送方帐号(一个OpenID) 35 | $fromUsername = $postObj->FromUserName; 36 | # toUsername : 开发者微信号 37 | $toUsername = $postObj->ToUserName; 38 | # keyword : 发送过来的内容 39 | $keyword = trim($postObj->Content); 40 | # rx_type : 请求类型 41 | $rx_type = trim($postObj->MsgType); 42 | # rx_event : 操作的事件 43 | $rx_event = $postObj->Event; 44 | # 服务器时间戳 45 | $time = time(); 46 | # 这里的XML格式不能改变,是微信规定的格式,里面的参数使用[%s]占位符占用,到时候填充完成,再发送回给微信 47 | $textTpl = " 48 | 49 | 50 | %s 51 | 52 | 53 | 0 54 | "; 55 | 56 | # 事件类型 57 | if($rx_type == 'event'){ 58 | switch ($rx_event){ 59 | # 关注事件 60 | case 'subscribe': 61 | $contentStr = '感谢您关注【JunPHP】'."\n".'更多内容,敬请期待...'; 62 | # 返回类型 63 | $msgType = 'text'; 64 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType,$contentStr); 65 | # 填充完成之后,输出回给微信 66 | echo $resultStr; 67 | break; 68 | # 取消关注 69 | case 'unsubscribe': 70 | # 取消关注将无法发送消息给对方,这个事件一般只能进行一些数据删除处理 71 | $resultStr = ''; 72 | break; 73 | } 74 | } 75 | # 调用日志记录-方便出错则查看 76 | $this->Error_Log(array( 77 | 'OpenID' => $fromUsername, 78 | '开发者ID' => $toUsername, 79 | '发送内容' => $keyword, 80 | '请求类型' => $rx_type, 81 | '操作事件' => $rx_event, 82 | 'XML' => $resultStr 83 | ),false); 84 | }else { 85 | echo ""; 86 | exit; 87 | } 88 | } 89 | 90 | /** 91 | * @Title : 记录错误信息与查看部分信息 92 | * @Author : 小黄牛 93 | * @param array : $Arr_Title 一个一维数组自定义内容 94 | * @param bool : $Arr_Error 是否插入系统错误信息 95 | * @param string : $File 日志名 96 | * @return : 无 97 | */ 98 | private function Error_Log($Arr_Title,$Arr_Error=false,$File='Error_log.log'){ 99 | # 不是数组中断程序 100 | if (!is_array($Arr_Title)) {return false;} 101 | # 定义一个空的变量,用于存放日志TXT实体 102 | $Error_TXT = "自定义信息如下:\r\n"; 103 | # 解析Arr_Title 自定义日志内容 104 | foreach ($Arr_Title as $key=>$val){ 105 | $Error_TXT .= $key.':'.$val."\r\n"; 106 | } 107 | 108 | # 判断系统错误显示是否开启 109 | if ($Arr_Error === true) { 110 | # 获取刚发生的错误信息,并返回数组,无错返回null 111 | $Arr_Error = error_get_last(); 112 | # 不为空则执行错误解析 113 | if (isset($Arr_Error)) { 114 | $Error_TXT .= "系统错误信息如下:\r\n"; 115 | # 解析$Arr_Errore 系统错误信息 116 | foreach ($Arr_Title as $key=>$val){ 117 | $Error_TXT .= $key.':'.$val."\r\n"; 118 | } 119 | } 120 | } 121 | 122 | # 最后再写入两个换行符,以便追加查看 123 | $Error_TXT .= "\r\n\r\n"; 124 | # 最后写入日志 125 | error_log($Error_TXT,3,$File); 126 | } 127 | } -------------------------------------------------------------------------------- /8、PHP微信开发对自定义菜单进行改删查.php: -------------------------------------------------------------------------------- 1 | GetToken()); 19 | 20 | # 菜单结构(参考开发者手册) 21 | $data = '{ 22 | "button":[ 23 | { 24 | "type":"click", 25 | "name":"今日歌曲", 26 | "key":"V1001_TODAY_MUSIC" 27 | }, 28 | { 29 | "name":"菜单", 30 | "sub_button":[ 31 | { 32 | "type":"view", 33 | "name":"搜索", 34 | "url":"http://www.soso.com/" 35 | }, 36 | { 37 | "type":"view", 38 | "name":"视频", 39 | "url":"http://v.qq.com/" 40 | }, 41 | { 42 | "type":"click", 43 | "name":"赞一下我们", 44 | "key":"V1001_GOOD" 45 | }] 46 | }] 47 | }'; 48 | $Custom = new Custom_Menu(); 49 | # 创建菜单 50 | $Custom->createMenu($data); 51 | 52 | class Custom_Menu{ 53 | 54 | # 创建自定义菜单接口 55 | # $data : 菜单结构 56 | public function createMenu($data){ 57 | $url = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token='.ACCESS_TOKEN; 58 | $result = self::https_request($url, $data); 59 | # 这里可以打印返回值 60 | $data = array('创建菜单回调参数: ',$result); 61 | $this->Error_Log($data); 62 | } 63 | 64 | # 查询自定义菜单 65 | # return JSON格式的菜单结构 66 | public function searchMenu(){ 67 | $url = 'https://api.weixin.qq.com/cgi-bin/menu/get?access_token='.ACCESS_TOKEN; 68 | $result = self::https_request($url); 69 | # 这里可以打印返回值 70 | $data = array('查询菜单回调参数: ',$result); 71 | $this->Error_Log($data); 72 | } 73 | 74 | # 查询自定义菜单接口(包括菜单配置) 75 | # return JSON格式的菜单结构 76 | public function searchAllMenu(){ 77 | $url = 'https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token='.ACCESS_TOKEN; 78 | $result = self::https_request($url); 79 | # 这里可以打印返回值 80 | $data = array('查询配置菜单回调参数: ',$result); 81 | $this->Error_Log($data); 82 | } 83 | 84 | # 删除自定义菜单接口 85 | public function deleteMenu(){ 86 | $url = 'https://api.weixin.qq.com/cgi-bin/menu/delete?access_token='.ACCESS_TOKEN; 87 | $result = self::https_request($url); 88 | # 这里可以打印返回值 89 | $data = array('删除菜单回调参数: ',$result); 90 | $this->Error_Log($data); 91 | } 92 | 93 | # 作者:焰哥 - 用于微信接口数据传输的万能函数 94 | private static function https_request($url, $data = null){ 95 | # 初始化一个cURL会话 96 | $curl = curl_init(); 97 | 98 | //设置请求选项, 包括具体的url 99 | curl_setopt($curl, CURLOPT_URL, $url); 100 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); //禁用后cURL将终止从服务端进行验证 101 | curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 102 | 103 | if (!empty($data)){ 104 | curl_setopt($curl, CURLOPT_POST, 1); //设置为post请求类型 105 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data); //设置具体的post数据 106 | } 107 | 108 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 109 | $response = curl_exec($curl); //执行一个cURL会话并且获取相关回复 110 | curl_close($curl); //释放cURL句柄,关闭一个cURL会话 111 | 112 | return $response; 113 | } 114 | 115 | /** 116 | * @Title : 记录错误信息与查看部分信息 117 | * @Author : 小黄牛 118 | * @param array : $Arr_Title 一个一维数组自定义内容 119 | * @param bool : $Arr_Error 是否插入系统错误信息 120 | * @param string : $File 日志名 121 | * @return : 无 122 | */ 123 | private function Error_Log($Arr_Title,$Arr_Error=false,$File='Error_log.log'){ 124 | # 不是数组中断程序 125 | if (!is_array($Arr_Title)) {return false;} 126 | # 定义一个空的变量,用于存放日志TXT实体 127 | $Error_TXT = "自定义信息如下:\r\n"; 128 | # 解析Arr_Title 自定义日志内容 129 | foreach ($Arr_Title as $key=>$val){ 130 | $Error_TXT .= $key.':'.$val."\r\n"; 131 | } 132 | 133 | # 判断系统错误显示是否开启 134 | if ($Arr_Error === true) { 135 | # 获取刚发生的错误信息,并返回数组,无错返回null 136 | $Arr_Error = error_get_last(); 137 | # 不为空则执行错误解析 138 | if (isset($Arr_Error)) { 139 | $Error_TXT .= "系统错误信息如下:\r\n"; 140 | # 解析$Arr_Errore 系统错误信息 141 | foreach ($Arr_Title as $key=>$val){ 142 | $Error_TXT .= $key.':'.$val."\r\n"; 143 | } 144 | } 145 | } 146 | 147 | # 最后再写入两个换行符,以便追加查看 148 | $Error_TXT .= "\r\n\r\n"; 149 | # 最后写入日志 150 | error_log($Error_TXT,3,$File); 151 | } 152 | } 153 | 154 | -------------------------------------------------------------------------------- /6、微信语音与图片识别.php: -------------------------------------------------------------------------------- 1 | 基本配置 -> 服务器配置中填写的Token令牌值 14 | define("TOKEN", "weixin"); 15 | # 实例化示例类 16 | $wechatObj = new wechatCallbackapiTest(); 17 | # 由于数字认证已经通过,valid()与checkSignature()方法删除掉,没有作用了 18 | # 只需要留下responseMsg方法,作为回调方法 19 | $wechatObj->responseMsg(); 20 | 21 | 22 | class wechatCallbackapiTest { 23 | // 第一次绑定服务器地址的时候,用不到这个方法 24 | public function responseMsg() { 25 | # 获得数据包的信息 26 | $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; 27 | 28 | # 如果数据包内的信息不为空 29 | if (!empty($postStr)){ 30 | # XML文件的解析依赖libxml库,libxml_disable_entity_loader函数,是为了安全性,防止入侵者通过协议注入XML向服务器发起攻击 31 | libxml_disable_entity_loader(true); 32 | # 把XML编译成一个Class 33 | $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); 34 | # FromUserName : 发送方帐号(一个OpenID) 35 | $fromUsername = $postObj->FromUserName; 36 | # toUsername : 开发者微信号 37 | $toUsername = $postObj->ToUserName; 38 | # keyword : 发送过来的内容 39 | $keyword = trim($postObj->Content); 40 | # rx_type : 请求类型 41 | $rx_type = trim($postObj->MsgType); 42 | # 服务器时间戳 43 | $time = time(); 44 | # 这里的XML格式不能改变,是微信规定的格式,里面的参数使用[%s]占位符占用,到时候填充完成,再发送回给微信 45 | $textTpl = " 46 | 47 | 48 | %s 49 | 50 | 51 | 0 52 | "; 53 | 54 | switch ($rx_type){ 55 | # 语音消息 56 | case 'voice': 57 | # 语音内容 58 | $recognition = $postObj->Recognition; 59 | # 语音格式 60 | $format = $postObj->Format; 61 | $contentStr = '你发送的是语音消息'."\n".'语言格式为:'.$format."\n".'语音内容为:'.$recognition; 62 | # 返回类型 63 | $msgType = 'text'; 64 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType,$contentStr); 65 | # 填充完成之后,输出回给微信 66 | echo $resultStr; 67 | # 调用日志记录-方便出错则查看 68 | $this->Error_Log(array( 69 | 'OpenID' => $fromUsername, 70 | '开发者ID' => $toUsername, 71 | '发送内容' => $keyword, 72 | '请求类型' => $rx_type, 73 | '语音格式' => $format, 74 | '语音内容' => $recognition, 75 | 'XML' => $resultStr 76 | ),false); 77 | break; 78 | # 图片消息 79 | case 'image': 80 | # 图片链接 81 | $PicUrl = $postObj->PicUrl; 82 | # 返回类型 83 | $msgType = 'text'; 84 | $contentStr = '您的图片链接地址为:'.$PicUrl; 85 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType,$contentStr); 86 | # 填充完成之后,输出回给微信 87 | echo $resultStr; 88 | # 调用日志记录-方便出错则查看 89 | $this->Error_Log(array( 90 | 'OpenID' => $fromUsername, 91 | '开发者ID' => $toUsername, 92 | '发送内容' => $keyword, 93 | '请求类型' => $rx_type, 94 | '图片链接' => $PicUrl, 95 | 'XML' => $resultStr 96 | ),false); 97 | break; 98 | } 99 | 100 | }else { 101 | echo ""; 102 | exit; 103 | } 104 | } 105 | 106 | /** 107 | * @Title : 记录错误信息与查看部分信息 108 | * @Author : 小黄牛 109 | * @param array : $Arr_Title 一个一维数组自定义内容 110 | * @param bool : $Arr_Error 是否插入系统错误信息 111 | * @param string : $File 日志名 112 | * @return : 无 113 | */ 114 | private function Error_Log($Arr_Title,$Arr_Error=false,$File='Error_log.log'){ 115 | # 不是数组中断程序 116 | if (!is_array($Arr_Title)) {return false;} 117 | # 定义一个空的变量,用于存放日志TXT实体 118 | $Error_TXT = "自定义信息如下:\r\n"; 119 | # 解析Arr_Title 自定义日志内容 120 | foreach ($Arr_Title as $key=>$val){ 121 | $Error_TXT .= $key.':'.$val."\r\n"; 122 | } 123 | 124 | # 判断系统错误显示是否开启 125 | if ($Arr_Error === true) { 126 | # 获取刚发生的错误信息,并返回数组,无错返回null 127 | $Arr_Error = error_get_last(); 128 | # 不为空则执行错误解析 129 | if (isset($Arr_Error)) { 130 | $Error_TXT .= "系统错误信息如下:\r\n"; 131 | # 解析$Arr_Errore 系统错误信息 132 | foreach ($Arr_Title as $key=>$val){ 133 | $Error_TXT .= $key.':'.$val."\r\n"; 134 | } 135 | } 136 | } 137 | 138 | # 最后再写入两个换行符,以便追加查看 139 | $Error_TXT .= "\r\n\r\n"; 140 | # 最后写入日志 141 | error_log($Error_TXT,3,$File); 142 | } 143 | } -------------------------------------------------------------------------------- /20、PHP微信开发 JS-SDK配置,jsapi_ticket权限签名获取.php: -------------------------------------------------------------------------------- 1 | GetToken()); 44 | $WeiXin = new WeiXin(); 45 | # 获取签名 46 | var_dump($WeiXin->GetTicket()); 47 | 48 | class WeiXin{ 49 | private static $AppToken_Url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi';// 获取jsapi_ticket的地址 50 | private static $Ticket_Time = 6600;// 过期时间,单位秒,默认110分钟 51 | private static $Ticket_Length = 15;// nonceStr随机签名参数的长度 52 | 53 | # 验证jsapi_ticket有效期,有效则返回最新一条access_token,没则更新 54 | public function GetTicket(){ 55 | # 获取ticket 56 | $url = self::Weixin_Url(); 57 | $DB = new Model_2(); 58 | $info = $DB->find("select * from jsapi_ticket where url = '$url'"); 59 | # 一条都没有,更新 60 | if (!$info) { 61 | return self::SaveTicket(); 62 | } 63 | # 计算出过期时间 64 | $time = time() + (self::$Ticket_Time); 65 | # 将过期时间进行对比 - 如果当前时间比库存时间大,则更新Access_Token,否则返回现在的Access_Token 66 | if (time() >= $info['out_time']){ 67 | return self::SaveTicket(); 68 | } 69 | return $info; 70 | } 71 | 72 | 73 | # 将Access_Token植入占位符 - 并请求到jsapi_ticket 74 | private static function Weixin_Ticket(){ 75 | $url = sprintf( self::$AppToken_Url, ACCESS_TOKEN); 76 | # 发起请求 77 | $result = self::https_request($url); 78 | self::Error_Log(array( 79 | '请求ticket时返回的JSON' => $result 80 | ));//记录日志,以防报错 81 | $res = json_decode($result,true); 82 | # 返回jsapi_ticket 83 | return $res['ticket']; 84 | } 85 | 86 | # 更新签名 87 | private static function SaveTicket(){ 88 | # 获取参数 89 | $data = self::Weixin_Sha1(); 90 | # 计算出过期时间 91 | $timestamp = $data['timestamp']; 92 | $time = $timestamp + (self::$Ticket_Time); 93 | $url = $data['url']; 94 | $noncestr = $data['noncestr'];// 随机字符串 95 | $sign = $data['sign'];// 签名字符串 96 | # 查询是否存在该签名 97 | $DB = new Model_2(); 98 | $info = $DB->find("select id from jsapi_ticket where url = '$url'"); 99 | # 存在数据,则修改 100 | if($info){ 101 | $sql = "UPDATE jsapi_ticket SET url='$url',timestamp='$timestamp',noncestr='$noncestr',signature='$sign',out_time='$time' WHERE id = ".$info['id']; 102 | }else{ 103 | # 不存在写入 104 | $sql = "INSERT INTO jsapi_ticket (url,timestamp,noncestr,signature,out_time) VALUES ('$url','$timestamp','$noncestr','$sign','$time')"; 105 | } 106 | $DB->Sql($sql); 107 | return $data; 108 | } 109 | 110 | # 进行权限签名加密 111 | private static function Weixin_Sha1(){ 112 | # 生成签名的时间戳 113 | $timestamp = time(); 114 | # 生成签名的随机字符串 115 | $noncestr = self::Weixin_Rand(); 116 | # 生成签名的jsapi_ticket 117 | $jsapi_ticket = self::Weixin_Ticket(); 118 | # 生成签名的url 119 | $url = self::Weixin_Url(); 120 | # 组合成数组 - 手动字典序 121 | $tmpArr = array( 122 | 'jsapi_ticket' => $jsapi_ticket, 123 | 'noncestr' => $noncestr, 124 | 'timestamp' => $timestamp, 125 | 'url' => $url 126 | ); 127 | # 合成键值兑换字符串 128 | $str = ''; 129 | foreach ($tmpArr as $key => $val) { 130 | $str .= $key.'='.$val.'&'; 131 | } 132 | $str = rtrim($str, '&'); 133 | # 进行sha1加密签名 134 | $tmpStr = sha1( $str ); 135 | # 将需要保存到数据库的内容组合成数组,并返回 136 | $data = array( 137 | 'noncestr' => $noncestr, // 随机字符串 138 | 'timestamp'=> $timestamp,// 时间戳 139 | 'url' => $url, // 识别url 140 | 'sign' => $tmpStr // 签名字符串 141 | ); 142 | self::Error_Log(array( 143 | '生成的签名JSON' => json_encode($data) 144 | ));//记录日志,以防报错 145 | return $data; 146 | } 147 | 148 | # 生成随机字符串 149 | private static function Weixin_Rand(){ 150 | $pattern = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLOMNOPQRSTUVWXYZ'; 151 | $key = ''; 152 | for($i=0 ;$i$val){ 204 | $Error_TXT .= $key.':'.$val."\r\n"; 205 | } 206 | 207 | # 判断系统错误显示是否开启 208 | if ($Arr_Error === true) { 209 | # 获取刚发生的错误信息,并返回数组,无错返回null 210 | $Arr_Error = error_get_last(); 211 | # 不为空则执行错误解析 212 | if (isset($Arr_Error)) { 213 | $Error_TXT .= "系统错误信息如下:\r\n"; 214 | # 解析$Arr_Errore 系统错误信息 215 | foreach ($Arr_Title as $key=>$val){ 216 | $Error_TXT .= $key.':'.$val."\r\n"; 217 | } 218 | } 219 | } 220 | 221 | # 最后再写入两个换行符,以便追加查看 222 | $Error_TXT .= "\r\n\r\n"; 223 | # 最后写入日志 224 | error_log($Error_TXT,3,$File); 225 | } 226 | 227 | } 228 | 229 | # PDO类 230 | class Model_2{ 231 | protected static $dbMs = 'mysql';// 数据库类型 232 | protected static $dbHost = 'bdm23250574.my3w.com';// 数据库主机名 233 | protected static $dbName = 'localhost';// 数据库名称 234 | protected static $dbCharset = 'utf8';// 数据库编码 235 | protected static $dbUser = '';// 数据库连接用户名 236 | protected static $dbPwd = '';// 数据库密码 237 | 238 | private $instance;// 数据库PDO连接实例 239 | 240 | # 获得PDO实例 241 | public function __construct(){ $this->dbPdo();} 242 | 243 | # 执行PDO链接 244 | private function dbPdo(){ 245 | $dbn = self::$dbMs.':host='.self::$dbHost.';dbname='.self::$dbName.';charset='.self::$dbCharset; 246 | $dbh = new PDO($dbn,self::$dbUser,self::$dbPwd); 247 | $this->instance = $dbh; 248 | } 249 | 250 | # 执行SELECT查询获取单条记录,返回一维数组 251 | public function find($Sql){ 252 | $pdo = $this->instance; 253 | $res = $pdo->query($Sql); 254 | $res->setFetchMode(PDO::FETCH_ASSOC); //数字索引方式 255 | return $res->fetch(); 256 | } 257 | 258 | # 添加操作 259 | public function Sql($Sql){ 260 | $pdo = $this->instance; 261 | return $pdo->exec($Sql); 262 | } 263 | } 264 | 265 | /** 266 | * 表结构如下: 267 | CREATE TABLE IF NOT EXISTS `jsapi_ticket` ( 268 | `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', 269 | `url` varchar(150) CHARACTER SET utf8 NOT NULL COMMENT 'URL子键,用于识别对应路由', 270 | `timestamp` varchar(20) CHARACTER SET utf8 NOT NULL COMMENT '生成签名时的时间戳', 271 | `noncestr` varchar(100) CHARACTER SET utf8 NOT NULL COMMENT '生成签名的随机串', 272 | `signature` varchar(100) CHARACTER SET utf8 NOT NULL COMMENT '最终生成的签名', 273 | `out_time` varchar(20) CHARACTER SET utf8 NOT NULL COMMENT '过期时间戳为2小时-10分钟', 274 | PRIMARY KEY (`id`) 275 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='微信的jsapi_ticket' AUTO_INCREMENT=1 ; 276 | */ 277 | --------------------------------------------------------------------------------