微信公众号裂变式营销代码实现,先讲下基础原理,先生成带有用户参数的二维码,然后用php自带的gd库处理,生成带有用户头像,昵称,参数二维码,营销信息的自定义图片,再将图片传入微信公众号临时素材,当其他用户扫描这个专属推荐码的时候,获取用户的昵称返回给推荐者,并存入数据库,以记录当前有多少人扫描了二维码。
技术难点:
1.gd库处理图片,以前没玩过gd库,gd库很难用,建议如果不懂gd库,可以直接尝试其他的php图像处理扩展。
2.生成用户参数二维码,参数二维码选择临时二维码,参数选择字符串参数,字符串是推荐者的openid,因为openid是唯一的,是用户的标识,当然你也可以自己为用户设置标识,而且效率更高。
3.判断关注事件,是否是通过参数二维码进来的,判断方法可查微信公众号开发文档的关注事件推送。
4.应用到的技术:PHP,curl扩展,gd扩展,mysqli,
话不多说,直接上代码,还有其他想了解的,直接留言。
第一段代码,yanzheng.php,用来接收微信端返回的信息的,如果自己有,请不要照抄,直接看关注事件部分以及自定义菜单,有注释。
<?php /** * wechat php test */ //define your token // session_start(); //定义TOKEN秘钥 define("TOKEN", "weixin"); //实例化微信对象 $wechatObj = new wechatCallbackapiTest(); //验证成功后注释valid方法 // $wechatObj->valid(); //开启自动回复功能 $wechatObj->responseMsg(); //定义类文件 class wechatCallbackapiTest { //实现valid验证方法:实现对接微信公众平台 public function valid() { //接受随机字符串 $echoStr = $_GET["echostr"]; //valid signature , option //进行用户数字签名验证 if($this->checkSignature()){ //如果成功,则返回接受到的随机字符串 echo $echoStr; //退出 exit; } } //定义自动回复功能 public function responseMsg() { //get post data, May be due to the different environments //接受用户端发送过来的xml数据 $postStr = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : file_get_contents("php://input"); //extract post data //判断xml数据是否为空 if (!empty($postStr)){ /* libxml_disable_entity_loader is to prevent XML eXternal Entity Injection, the best way is to check the validity of xml by yourself */ libxml_disable_entity_loader(true); //通过simplexml进行xml解析 $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); //接受微信的手机端 $fromUsername = $postObj->FromUserName; //微信公众平台 $toUsername = $postObj->ToUserName; //接受用户发送的关键词 $keyword = trim($postObj->Content); //1.接受用户消息类型 $msgType = $postObj -> MsgType; //时间戳 $time = time(); //事件类型 $event = $postObj->Event; //自定义菜单事件K值 $eventkey = $postObj->EventKey; $ticket=$postObj->Ticket; //文本发送模板 $textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> <FuncFlag>0</FuncFlag> </xml>"; //图片发送模板 $imageTpl = "<xml> <ToUserName>< ![CDATA[%s] ]></ToUserName> <FromUserName>< ![CDATA[%s] ]></FromUserName> <CreateTime>%s</CreateTime> <MsgType>< ![CDATA[%s] ]></MsgType> <Image> <MediaId>< ![CDATA[%s] ]></MediaId> </Image> </xml> "; //关注事件 if($event=='subscribe') { $msgType = "text"; $contentStr = "感谢关注德盛康大药房! 您可以\n <a href='https://m.xxxx.com/ceshi.php'>在线购药</a>\n <a href='https://m.xxxx.com/zixunyaoshi'>药品咨询</a>\n <a href='https://m.xxxx.com/weixin/lxfs.html'>联系门店</a>"; $resultStr = sprintf($textTpl,$fromUsername,$toUsername,$time,$msgType,$contentStr); echo $resultStr; if(isset($eventkey)){ $canshu = substr($eventkey,8); $data = array('canshu' =>$canshu,'openid'=>$fromUsername ); hurl("https://m.xxxxx.com/weixin/moban2.php",$data); } } //扫描带参数的二维码的图片 // if($event=='subscribe' && isset($eventkey)){ // // $data = $eventkey; // // hurl("https://m.39dsk.com/weixin/moban2.php",$data); // // exit("success"); // $msgType = "text"; // $contentStr = substr($eventkey,8); // $resultStr = sprintf($textTpl,$fromUsername,$toUsername,$time,$msgType,$contentStr); // echo $resultStr; // } //自定义菜单事件 if ($event=='CLICK' && $msgType=='event') { if ($eventkey == "jfhg") { $contentStr = "您点击了积分换购,很抱歉,该功能未上线!"; $msgType = "text"; $resultStr = sprintf($textTpl,$fromUsername,$toUsername,$time,$msgType,$contentStr); echo $resultStr; } if ($eventkey == "mfly") { $data = $fromUsername; $contentStr = "已生成您的专属推荐码,邀请10位好友扫描关注我们,可免费领取XXX,邀请码稍有延迟,如不能生成请再次点击免费领药"; $msgType = "text"; $resultStr = sprintf($textTpl,$fromUsername,$toUsername,$time,$msgType,$contentStr); echo $resultStr; hurl("https://m.xxxxx.com/weixin/weweima.php",$data); } } //用户消息事件 if($msgType=='text'&&$keyword=="1"){ $msgType = "text"; $contentStr = "00"; $resultStr = sprintf($textTpl,$fromUsername,$toUsername,$time,$msgType,$contentStr); echo $resultStr; } if ($msgType=='text'&&$keyword=="本期活动") { // $msgType = "text"; // $contentStr = "22"; // $resultStr = sprintf($textTpl,$fromUsername,$toUsername,$time,$msgType,$contentStr); // echo $resultStr; include_once "kefujiekou2.php"; } exit("success"); } } private function checkSignature() { // you must define TOKEN by yourself //判断是否定义了TOKEN,如果没有就抛出一个异常 if (!defined("TOKEN")) { throw new Exception('TOKEN is not defined!'); } $signature = $_GET["signature"];//接受微信加密签名 $timestamp = $_GET["timestamp"];//接受时间戳 $nonce = $_GET["nonce"];//接受随机数 $token = TOKEN;//把TOKEN常量赋值给$token //把相关参数组装成数组 $tmpArr = array($token, $timestamp, $nonce); // use SORT_STRING rule //排序 sort($tmpArr, SORT_STRING); //把排序后的数组转换成字符串 $tmpStr = implode( $tmpArr ); //通过哈希算法加密 $tmpStr = sha1( $tmpStr ); //与加密签名进行对比 if( $tmpStr == $signature ){ //相同返回true return true; }else{ //不同返回false return false; } } } function hurl($a,$data){ $th = curl_init();//初始化curl实例 curl_setopt($th,CURLOPT_URL,$a); curl_setopt($th, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($th, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($th, CURLOPT_TIMEOUT, 1); curl_setopt($th, CURLOPT_RETURNTRANSFER, 1); curl_setopt($th, CURLOPT_POST, 1); curl_setopt($th, CURLOPT_POSTFIELDS, $data); $zz = curl_exec($th);//执行curl curl_close($th);//关闭curl return $zz; } ?>
第二段代码,erweima .php,主要是对图片进行处理,获取各种参数,只不过有图片保存到本地和上传到微信服务器,所以消耗时间过长,大家有什么好方法避免,欢迎交流。
<?php header("Content-type:text/html;charset=utf-8"); $post = file_get_contents('php://input');//设置post消息可读 $fromUsername = $_POST[0];//接收yanzheng.php传来的信息,参加活动的用户ID // print_r($_POST[0]); include_once "access_token.php";//获取微信公众号的access_token,微信公众号为验证服务器的身份,access_token是必须的 $url0 = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=".$access_token."&openid=".$fromUsername."&lang=zh_CN"; $result0 = https_request($url0); $a0 = json_decode($result0,true);//通过openid获取用户的头像和昵称 // echo $a0['nickname'] , $a0['headimgurl']; $jsonmenu = '{"expire_seconds": 2592000, "action_name": "QR_STR_SCENE", "action_info": {"scene": {"scene_str" : "'.$fromUsername.'"}}}'; $url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=".$access_token; $result = https_request($url, $jsonmenu);//生成用户参数二维码的ticket,参数二维码需要用ticket换取,微信公众号规定,为什么这么规定,反正我是想不明白 $a = json_decode($result,true); $b = UrlEncode($a['ticket']) ;//获取ticket $url2 = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=".$b; $result2 = https_request($url2); //参数二维码 // var_dump($result2); //以下是GD库处理图片部分,不解释了,看GD库的文档吧 $bg = imagecreatefrompng("images/ceshi.png"); $img_info = getimagesize('images/ceshi.png'); $img_w = $img_info[0]; $img_h = $img_info[1]; $im = imagecreatetruecolor($img_w, $img_h); $black = imagecolorallocate($im, 0, 0, 0); $red = imagecolorallocate($im, 255, 0, 0); imagecopy($im,$bg,0,0,0,0,$img_w,$img_h); $font = "font/msyh.ttf"; $text = $a0['nickname']; $text2 = '免费送药,免费咨询,快来和我一起体验吧'; imagettftext($im, 14, 0, 300, 970, $black, $font,$text); imagettftext($im, 18, 0, 140, 1020, $red, $font,$text2); $img2 = imagecreatefromstring($result2);//带有参数的二维码 imagecopyresized($im, $img2, 200, 470, 0, 0,320,320,430, 430); $img3 = imagecreatefromjpeg($a0['headimgurl']);//用户头像图片 imagecopyresized($im, $img3, 300, 830, 0, 0,110,103,110, 103); $img4 = imagecreatefrompng('images/touxiang.png');//二维码中心的头像,二维码被遮盖一小部分不影响识别,可以参考二维码原理 imagecopyresized($im, $img4, 320, 600, 0, 0,80,80,500, 500); $img5 = imagecreatefrompng('images/yx.png');//圆角图片 imagecopyresized($im, $img5, 300, 830, 0, 0,110,110,110, 110); header('Content-Type: image/png'); imagepng($im,'images/'.$fromUsername.'.png'); imagedestroy($im); //GD库图片处理到此结束,将图片储存到了'images/'.$fromUsername.'.png'! //以下是 $file = __DIR__."\images\\".$fromUsername.".png";//取出图片 // echo $file; $obj = new CurlFile($file); //CurlFile,php高于5.5,上传文件必须要用CurlFile $post['media'] = $obj; $url = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=".$access_token."&type=image"; $result = https_request($url,$post); //将图片信息上传至临时素材,获取素材ID $zz = json_decode($result,true); $data = '{ "touser":"'.$fromUsername.'", "msgtype":"image", "image": { "media_id":"'.$zz['media_id'].'" } }'; $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=".$access_token; $result = https_request($url,$data); //利用客服接口,发送图片信息到用户 // var_dump($result); function https_request($url,$data = null){ $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); 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); $output = curl_exec($curl); curl_close($curl); return $output; } ?>
第三段代码,用户扫描了带参数的二维码,将事件通过模板消息的方式推送给推荐者,让他知道是谁扫描了该二维码、
<?php header("Content-type:text/html;charset=utf-8"); $post = file_get_contents('php://input'); $eventkey = $_POST['canshu'];//获取关注事件推送来的信息 $fromUsername = $_POST['openid']; // $eventkey = "ou1RJxE7SYBEw4DBOBs8EBL0egZ0"; // $fromUsername = "ou1RJxJ0Y7yzT5H9_DG1jp0ybIy0"; if ($eventkey!=$fromUsername) {//判断不能自己扫自己,如果不加,那么用户将图片保存到本地,然后取消关注,扫自己的二维码关注是可行的。 include_once "access_token.php";//微信验证 $url0 = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=".$access_token."&openid=".$fromUsername."&lang=zh_CN"; $result0 = https_request($url0); $a0 = json_decode($result0,true); $name = $a0['nickname'];//获取扫描者的昵称 include_once "coom.php";//连接数据库,将事件存入数据库,以便判断有多少人扫描了二维码 mysqli_query($conn , "set names utf8"); $sql = "INSERT INTO biaoming ". "(yqz,byqz) ". "VALUES ". "('$eventkey','$fromUsername')"; $sql2 = "SELECT * FROM biaoming where yqz = '$eventkey'"; $sql3 = "UPDATE biaoming SET wancheng=1 WHERE yqz ='$eventkey'"; //biaoming = “表名”,yqz="推荐者的ID" ,byqz = "扫描者的ID" mysqli_select_db( $conn, 'liuyanfankui'); $retval = mysqli_query( $conn, $sql ); $retval2 = mysqli_query( $conn, $sql2 ); $num = mysqli_num_rows($retval2); $hsx = 10-$num; if ($hsx<=0 ) { $tt = "任务完成,请进入微信商城-->个人中心-->修改地址,填写收件信息,我们会尽快为您配送,如已填写,请忽略"; $retval3 = mysqli_query( $conn, $sql3 ); }else{ $tt = "邀请10位好友加入我们,就能获得德盛康大药房免费赠送的XXX,已邀请".$num."位,还差".$hsx."位"; } if (!$retval) { echo "插入失败"; } mysqli_close($conn); //以下发送模板消息,请查看微信公众号开发文档 $time = date("Y-m-d H:i:s"); $jsonmenu = ' { "touser":"'.$eventkey.'", "template_id":"模板素材ID", "data":{ "first": { "value":"'.$name.'通过您的二维码成为了我们的朋友!", "color":"#173177" }, "keyword1":{ "value":"免费领药", "color":"#173177" }, "keyword2": { "value":"'.$time.'", "color":"#173177" }, "remark":{ "value":"'.$tt.'", "color":"#ff0000" } } }'; $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=".$access_token; $result = https_request($url,$jsonmenu); var_dump($result); //以上为发送模板消息 } function https_request($url,$data = null){ $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); 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); $output = curl_exec($curl); curl_close($curl); return $output; } ?>
此,功能基本开发完毕,但也有一些不完美的地方,最主要的是保存参数二维码到本地,然后上传参数二维码到微信服务器,这段代码耗时太长,欢迎学习交流。
转载自:https://blog.csdn.net/weixin_41797287/article/details/80220935
本文来自博客园,作者:孙龙-程序员,转载请注明原文链接:https://www.cnblogs.com/sunlong88/articles/12690454.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
2019-04-13 thrift之php,python使用TServerSocket并发 处理请求