2016-09-09 14:31:11 u010585120 阅读数 2674
  • 微信公众号开发5-自定义菜单-微信开发php

    微信公众平台开发之自定义菜单管理是子恒老师《微信公众平台开发》视频教程的第5部。详细讲解了用php开发微信,对微信公众平台中的自定义管理开发。内容包含微信添加菜单,获取自定义菜单配置,删除菜单等等。欢迎反馈,微信/QQ:68183131

    5686 人正在学习 去看看 秦子恒
场景
进入微信公众号 
点菜单 跳到 自己开发的jsp页面 
点链接 跳转到 公众号平台(官方)发布的图文页面 
点返回按钮没用 ios   不能返回到自己开发的jsp页面

(安卓里是好的)



解决方案:

在跳转路径后面加上:

#wechat_redirect

2016-09-14 18:03:32 kirsten_z 阅读数 138
  • 微信公众号开发5-自定义菜单-微信开发php

    微信公众平台开发之自定义菜单管理是子恒老师《微信公众平台开发》视频教程的第5部。详细讲解了用php开发微信,对微信公众平台中的自定义管理开发。内容包含微信添加菜单,获取自定义菜单配置,删除菜单等等。欢迎反馈,微信/QQ:68183131

    5686 人正在学习 去看看 秦子恒

1、android 和 iphone 区别

1)进入多层页面后,返回前一页​

微信开发 =》点击自定义菜单 =》腾讯授权返回code码=》判定后进入目标页面

通过腾讯授权获取的code一次有效​,iphone点击左上角返回按钮,重新载入前一个页面,code码是失效,报错

这里写图片描述

​解决方式:

设置session:将需要判定的变量,在第一次进入目标页面时,​保存在session里,下次重载如该页面时,判定session

use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Redirect;

class SignController extends BaseController
{
    public function getIndex()
    {
        //判断weixin_id的来源,获取weixin_id
        if(Session::has('openid')){
            $weixin_id = Session::get('openid');
        }elseif(isset($_GET["code"])){
            $weixin_id = getOpenId($_GET["code"]);
            //设置session记录weixin_id
            Session::put('openid', $weixin_id);
        }
        //判断微信id是否合法
        if(!$info=checkUserLegal($weixin_id)){
            $msgcontent="非法访问,请重新进入签到页面!";
            return View::make('front.bind.message')->with('msgcontent', $msgcontent);
            exit;
        }

2)显示日历

iPhone默认,数字可以拨打

解决方式:在现实日历页面添加标签

2、​判定后跳转到目标页面(laravel框架)

​1)点击目标页面入口,先行判定是否绑定账号,若无,则跳转到绑定页面

​return Redirect::to($url); //$url -- 目标页面路径

2)绑定后跳转到目标页面​

控制器层,需要获取目标页面的URL:设置session

Sesssion::put('from', $url);​ //$url -- 目标页面路径

​view层,需要判定是否存在session,获取,跳转

@if(Session::has('from'))​       
    {{Session::forget('from')}}
@endif
//判断是否在签到或订阅页面,若是则绑定后跳转到该页面
if($('#session_val').val()){
    setTimeout(function(){
        window.location.href =$('#session_val').val();
    }, 1000);
}​

setTimeout(callback, time) – 设置在指定时间执行callback方法

3、日期签到,连续签到日期效果显示

1)进入签到页面判定

获取本月已签到日期​,返回值到当前页

2)js判定,ready()方法​,显示效果

$(document).ready(function(e) {   
   //显示当前月份签到情况
   if($("#singed_days").val()){
       var days_arr = $("#singed_days").val().split(",");
       for(var i in days_arr){
          var select = "#fc-" + days_arr[i];
          $(select).parent().addClass("current_day");
       }
    }
});

var arr = val.split(“,”) ​将val值拆分成用 , 隔开的字符串数组arr
​for(var i in days_arr){} 循环判定相应键值i是否存在在arr中,并逐一进行相应处理

4、​环境配置问题

不同环境配置​不同,导致一些语法书写方法失效

php 高版本支持 数组语法 $arr = [ 1, 3, 4];

php 5.3以下不支持上面写法 ,支持 $arr = array(1, 3, 4);​

5、微信测试发布注意项

1)外网域名 是否正确 config里
2)APPID APPSECRET 是否正确 (微信公众号正式的)
3)​access_token 是否正确,是否有效

2015-08-31 08:45:04 lihuapiao 阅读数 2644
  • 微信公众号开发5-自定义菜单-微信开发php

    微信公众平台开发之自定义菜单管理是子恒老师《微信公众平台开发》视频教程的第5部。详细讲解了用php开发微信,对微信公众平台中的自定义管理开发。内容包含微信添加菜单,获取自定义菜单配置,删除菜单等等。欢迎反馈,微信/QQ:68183131

    5686 人正在学习 去看看 秦子恒

1.无后台管理的自定义菜单

             ①根据appId和appSecret获取acessToken

                                    a.向服务器发送请求 httpRequst(url,method,outPutStr)  返回jsonObject(包含了access_token和expires_in字段值)getString(""),getInt("")

                                                                      1)建立双向认证https请求(SSLContext.getInstance("SSL", "SunJSSE").init(KeyManager,TrustManager,SecureRandom).getSocketFactory())【https和ssl

WechatUtil.java

 

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.kerui.domains.community.entity.Ticket;
import com.kerui.domains.model.AccessToken;
import com.kerui.domains.model.AccessTokenByCode;
import com.kerui.domains.model.Menu;
public class WechatUtil{ 
	private static Logger log = LoggerFactory.getLogger(WechatUtil.class);
/**
     * access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。正常情况下access_token有效期为7200秒,重复获取将导致上次获取的access_token失效。
     * 公众号可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在开发模式中获得(需要已经成为开发者,且帐号没有异常状态)。
     * */
	
    //获取access_token的接口地址(GET) 限200(次/天)  
  	public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";  
  	// 菜单创建(POST) 限100(次/天)  
  	public static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
  	
  	
  	/* 使用接口创建自定义菜单后,开发者还可使用接口删除当前使用的自定义菜单
	 * https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN
	 */
	public final static String delete_menulist="https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN";
	
	//公众号可通过本接口来获取帐号的关注者列表,关注者列表由一串OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的)组成。一次拉取调用最多拉取10000个关注者的OpenID,可以通过多次拉取的方式来满足需求。 
	public final static String getwechatuser="https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN ";
	
	//获取微信关注列表超过10000(count>10000)
	public final static String getmoreweichatuser="https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID";
	
	//向微信关注用户发送信息;http请求方式:POST
	public final static String postinfotouser="https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN";

/**
	 * 获取access_token
	 * 
	 * @param appid
	 *            凭证
	 * @param appsecret
	 *            密钥
	 * @return
	 */
	public static AccessToken getAccessToken(String appid, String appsecret) {
		AccessToken accessToken = null;

		 String requestUrl = access_token_url.replace("APPID", appid).replace(
 				"APPSECRET", appsecret);
		JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
		// 如果请求成功
 		if (null != jsonObject) {
			 try {
				 accessToken = new AccessToken();
				accessToken.setToken(jsonObject.getString("access_token"));
				 accessToken.setExpiresIn(jsonObject.getInt("expires_in"));
			} catch (JSONException e) {
				 accessToken = null;
				// 获取token失败
 				log.error("获取token失败 errcode:{} errmsg:{}",
						 jsonObject.getInt("errcode"),
						 jsonObject.getString("errmsg"));
			 }
 		}
 		return accessToken;
 	}
	/**
	 * 创建菜单
	 * 
	 * @param menu
	 *            菜单实例
	 * @param accessToken
	 *            有效的access_token
	 * @return 0表示成功,其他值表示失败
	 */
	public static int createMenu(Menu menu, String accessToken) {
		int result = 0;

		// 拼装创建菜单的url
		String url = menu_create_url.replace("ACCESS_TOKEN", accessToken);
		// 将菜单对象转换成json字符串
		String jsonMenu = JSONObject.fromObject(menu).toString();
		// 调用接口创建菜单
		JSONObject jsonObject = httpRequest(url, "POST", jsonMenu);

		if (null != jsonObject) {
			if (0 != jsonObject.getInt("errcode")) {
				result = jsonObject.getInt("errcode");
				log.error("创建菜单失败 errcode:{} errmsg:{}",
						jsonObject.getInt("errcode"),
						jsonObject.getString("errmsg"));
			}
		}

		return result;
	}



/**
	 * 发起https请求并获取结果
	 * 
	 * @param requestUrl
	 *            请求地址
	 * @param requestMethod
	 *            请求方式(GET、POST)
	 * @param outputStr
	 *            提交的数据
	 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
	 */
	public static JSONObject httpRequest(String requestUrl,
			String requestMethod, String outputStr) {
		JSONObject jsonObject = null;
		StringBuffer buffer = new StringBuffer();
		try {
			// 创建SSLContext对象,并使用我们指定的信任管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			 // 从上述SSLContext对象中得到SSLSocketFactory对象
 			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
  			HttpsURLConnection httpUrlConn = (HttpsURLConnection) url
					.openConnection();
			  httpUrlConn.setSSLSocketFactory(ssf);

 			httpUrlConn.setDoOutput(true);
 			httpUrlConn.setDoInput(true);
			 httpUrlConn.setUseCaches(false);
 			// 设置请求方式(GET/POST)
			 httpUrlConn.setRequestMethod(requestMethod);

			if ("GET".equalsIgnoreCase(requestMethod))
 				httpUrlConn.connect();

			 // 当有数据需要提交时
			if (null != outputStr) {
 				OutputStream outputStream = httpUrlConn.getOutputStream();
				// 注意编码格式,防止中文乱码
 				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			 }

			 // 将返回的输入流转换成字符串
			InputStream inputStream = httpUrlConn.getInputStream();
			 InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream, "utf-8");
 			BufferedReader bufferedReader = new BufferedReader(
					 inputStreamReader);

			String str = null;
			 while ((str = bufferedReader.readLine()) != null) {
 				buffer.append(str);
			}
 			bufferedReader.close();
 			inputStreamReader.close();
			// 释放资源
                        inputStream.close();
                        inputStream = null;
                        httpUrlConn.disconnect();
 			jsonObject = JSONObject.fromObject(buffer.toString());
		} catch (ConnectException ce) {
			 log.error("Weixin server connection timed out.");
		} catch (Exception e) {
 			log.error("https request error:{}", e);
		}
 		return jsonObject;
 	}
}

MyX509TrustManager.java

/** 
 * 证书信任管理器(用于https请求) 
 * <br>
 * X509证书信任管理器类
 * <br>
 * 证书信任管理器类就是实现了接口X509TrustManager的类
 */  
public class MyX509TrustManager implements X509TrustManager {  
	/**
	 * 该方法检查客户端的证书,若不信任该证书则抛出异常。<br>
	 * 由于我们不需要对客户端进行认证,因此我们只需要执行默认的信任管理器的这个方法。<br>
	 * JSSE中,默认的信任管理器类为TrustManager。
	 * *
	 */
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {  
    }  
    
    /**
     * 该方法检查服务器的证书,若不信任该证书同样抛出异常。<br>
     * 通过自己实现该方法,可以使之信任我们指定的任何证书。<br>
     * 在实现该方法时,也可以简单的不做任何处理,即一个空的函数体,由于不会抛出异常,它就会信任任何证书。
     * */
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {  
    }  
    
    /**
     * 返回受信任的X509证书数组。
     * */
    public X509Certificate[] getAcceptedIssuers() {  
        return null;  
    }  
}  

SearchMenuManager.java

 private static Logger log = LoggerFactory.getLogger(SearchMenuManager.class);
        /**
         * access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。正常情况下access_token有效期为7200秒,重复获取将导致上次获取的access_token失效。
         * 公众号可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在开发模式中获得(需要已经成为开发者,且帐号没有异常状态)。
         * */
      
        public static void main(String[] args) {  
        	//个人测试账号
            String appId = "xxxxxxxx";
            String appSecret = "xxxxxxxxx";           
            //根据appId和appSecret获取accessToken
            AccessToken accessToken = WeixinUtil.<span style="color:#FF0000;">getAccessToken</span>(appId, appSecret);
            
            if(log.isInfoEnabled()){
            	log.info("accessToken {}", accessToken.getToken());
            }
            //创建自定义菜单
            
            if(null != accessToken){
            	int result = WeixinUtil.<span style="color:#FF0000;">createMenu</span>(<span style="color:#FF0000;">getMenu</span>(), accessToken.getToken());
            	 // 判断菜单创建结果  
                if (0 == result){
                    log.info("菜单创建成功!"); 
                }else{
                    log.info("菜单创建失败,错误码:" + result);  
                }
            }
          
        }

        /**
         * 自定义菜单组建
         * @return 菜单Menu
         */
		private static Menu getMenu() {
			ViewButton viewBtn1 = new ViewButton();
			viewBtn1.setName("tom");
			viewBtn1.setType("view");
			viewBtn1.setUrl(FileUtil.SERVER_PATH+"xlchen/tom");
			
			ViewButton viewBtn2 = new ViewButton();
			viewBtn2.setName("jerry");
			viewBtn2.setType("view");
			viewBtn2.setUrl(FileUtil.SERVER_PATH+"xlchen/jerry");
//			
//			ViewButton viewBtn3 = new ViewButton();
//			viewBtn3.setName("刮刮乐");
//			viewBtn3.setType("view");
//			viewBtn3.setUrl("");
			
			CommonButton clickBtn1 = new CommonButton();
			clickBtn1.setName("大转盘");
			clickBtn1.setType("click");
			clickBtn1.setKey("1");
			
			CommonButton clickBtn2 = new CommonButton();
			clickBtn2.setName("砸金蛋");
			clickBtn2.setType("click");
			clickBtn2.setKey("2");
			
//			CommonButton clickBtn3 = new CommonButton();
//			clickBtn3.setName("刮刮乐");
//			clickBtn3.setType("click");
//			clickBtn3.setKey("3");
//			
//			ViewButton viewBtn4= new ViewButton();
//			viewBtn4.setName("查看中奖纪录");
//			viewBtn4.setType("view");
//			viewBtn4.setUrl("");
//			
//			ViewButton viewBtn5 = new ViewButton();
//			viewBtn5.setName("关于我们");
//			viewBtn5.setType("view");
//			viewBtn5.setUrl("");
//			
//			ViewButton viewBtn6 = new ViewButton();
//			viewBtn6.setName("投诉建议");
//			viewBtn6.setType("view");
//			viewBtn6.setUrl("");
			
			
			ComplexButton complexBtn = new ComplexButton();
			complexBtn.setName("顾客信息");
			complexBtn.setSub_button(new Button[]{viewBtn1,viewBtn2});
			
			ComplexButton complexBtn2 = new ComplexButton();
			complexBtn2.setName("活动介绍");
			complexBtn2.setSub_button(new Button[]{clickBtn1,clickBtn2});
			
			Menu menu = new Menu();
			menu.setButton(new Button[]{complexBtn,complexBtn2});
			
			return menu;
		}

    }
Button 为 以下 所有 Button 的父类。

ViewButton.java

   //view:跳转url
    private String type;  
    private String url;
    private String name;  
	  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
    public String getType() {
		return type;
    }
    public void setType(String type) {
		this.type = type;
    }
    public String getUrl() {
		return url;
    }
    public void setUrl(String url) {
		this.url = url;
    }  

CommonButton.java

//点击推事件:根据key值推送不同内容
private String type;  
private String key;  
private String name;  
	  
public String getName() {  
        return name;  
}  
  
public void setName(String name) {  
        this.name = name;  
}  
  
public String getType() {  
        return type;  
}  
  
public void setType(String type) {  
        this.type = type;  
}  
  
public String getKey() {  
        return key;  
}  
  
public void setKey(String key) {  
        this.key = key;  
}  

ComplexButton.java

    //组合菜单(一级菜单和二级菜单)
    private Button[] sub_button;  
    private String name;  
	  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
	  
    public Button[] getSub_button() {  
        return sub_button;  
    }  
  
    public void setSub_button(Button[] sub_button) {  
        this.sub_button = sub_button;  
    }  

以上为代码部分,前提还需要 配置 公众账号的 JS 安全域名。

这里以个人测试账号为例,登录微信个人测试账号 微信公众平台个人测试登录

登录完成之后,会看到对应的 appId 和 appsecret ,代码中需要使用到。下面有一栏叫做 JS接口安全域名

个人的话可以使用花生壳之类 映射一个域名,比如我这里填写的域名为:

194127e1f3.iok.la:21028

另外需要主要的是 上面代码中 的 ViewButton 在设置 url 的时候,该 url 也是有要求的,必须以 http 开头。



2018-02-02 15:50:33 chiangDeng 阅读数 2990
  • 微信公众号开发5-自定义菜单-微信开发php

    微信公众平台开发之自定义菜单管理是子恒老师《微信公众平台开发》视频教程的第5部。详细讲解了用php开发微信,对微信公众平台中的自定义管理开发。内容包含微信添加菜单,获取自定义菜单配置,删除菜单等等。欢迎反馈,微信/QQ:68183131

    5686 人正在学习 去看看 秦子恒

微信公众号点击菜单即可打开并登录微站的实现方法:

微信公众号点击菜单即可打开并登录微站实现步骤比较复杂,但很多微站在己用上了,本文对此进行整理归纳,相信可以给大家带来一定的参考借鉴价值。

现在大部分微站都通过用户的微信openid来实现自动登录。在我之前的开发中,用户通过点击一个菜单,公众号返回一个图文,用户点击这个图文才可以自动登录微站。但是如果你拥有高级接口,就可以实现点击菜单,打开网页就能获取这个openid,实现自动登录。
这里已经提到,必须要拥有高级接口的权限(服务号、企业号),开启了开发者模式。

1.设置回调地址

在微信公众平台后台“开发者中心”中找到“高级接口”下的“OAuth2.0网页授权”,后面有一个“修改”,点击之后就会弹出填写回调地址的对话框。具体如何授权,请点击这里学习。只有获得高级接口权限后,才能出现这个地方的“修改”。
注意,这里填写的是域名,不是带的网址,而且解释中很清楚,“授权回调域名配置规范为全域名”,也就是说带www和不带是不同的两个域名。因此我这里要填写如下图中的域名。

2. 创建菜单

创建菜单可以通过你的微站后台创建,如果没有开启开发者模式,也可以通过微信公众平台后台创建。
菜单使用点击打开链接的模式,也就是view模式。如果你是使用开发者模式,通过向微信提交如下代码,即可创建公众号菜单(开发者文档):

复制代码代码如下:
{
     "button":[
     { 
          "type":"view",
          "name":"登录微站",
          "url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid={在微信公众平台后台获取这个APPID}&redirect_uri={你填写的回调域名下的地址}&response_type=code&scope=snsapi_base&state=1#wechat_redirect"
      }]
}

代码1 要提交的菜单代码,下面要用到
APPID的获取位置就是上面你填写回调地址的那个“开发者中心”。下面我们用PHP来实现一下菜单提交:
复制代码代码如下:
<?php
function curl_info($appid,$secret) {
  $ch = curl_init(); 
  curl_setopt($ch, CURLOPT_URL, "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$secret);
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
  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)) {  
    echo 'Errno'.curl_error($ch);
  }
  curl_close($ch); 
  $arr= json_decode($tmpInfo,true);
  return $arr;
}
function curl_menu($ACCESS_TOKEN,$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)) {
    echo 'Errno'.curl_error($ch);
  }
  curl_close($ch); 
  $arr= json_decode($tmpInfo,true);
  return $arr;
}
function creat_menu() {
  $ACCESS_LIST= curl_info(APP_ID,APP_SCR);//获取到的凭证,你需要自己define APP_ID和APP_SCR(应用密钥),这个也是在微信公众平台后台开发者中心找
  if($ACCESS_LIST['access_token']!='') {
    $access_token = $ACCESS_LIST['access_token'];//获取到ACCESS_TOKEN
    $data = '把上面代码1拷贝黏贴在这里';
    $msg = curl_menu($access_token,preg_replace("#u([0-9a-f]+)#ie", "iconv('UCS-2', 'UTF-8', pack('H4', '1'))", $data));
    if($msg['errmsg']=='ok') {
      die('创建自定义菜单成功!');
    }
    else {
      die('创建自定义菜单失败!');
    }
  }
  else {
    die('创建失败,微信AppId或微信AppSecret填写错误');
  }
}
create_menu();
?>

代码2 用PHP来创建微信公众号菜单

代码2其实有点冗余了,核心部分用红色标出来了。就这样,你的微信公众号中应该很快就可以看到创建了一个“登录微站”的菜单。点击这个菜单就可以实现登录微站了。
如果你不需要PHP,可以直接在微信公众平台后台的菜单自定义中写链接就可以了。

在上图中的这个地方,选择打开链接的方式创建菜单。OK,接下来把上面那个链接放进去:

https://open.weixin.qq.com/connect/oauth2/authorize?appid={在微信公众平台后台获取这个APPID}&redirect_uri={你填写的回调域名下的地址}&response_type=code&scope=snsapi_base&state=1#wechat_redirect

创建菜单就可以了。
当然,你也有可能只需要在你自己的微信管理后台加入这个链接就可以了。

3.在回调页获取openid

细心的你可能已经发现了,上面的链接地址中含有参数scope=snsapi_base,而非scope=snsapi_userinfo,因为使用前者不需要用户点击一个授权按钮,直接跳转到回调页面,而后者需要点击授权按钮,不过点击授权按钮有好处,一是可以在没有关注公众号的情况下也可以授权,二是授权后可以获得用户的一些信息,如昵称、性别、所在地。但是我们是为了利用openid进行登录,所以直接选择前者就可以了。

点击菜单之后,经过微信authorize的处理,会跳转到你提交的回调地址(这里需要提醒,回调地址最好不要带参数,例如xxx/?callback=from_weixin,因为微信跳转到你的回调地址也要带参数,而这个参数就你需要的)。微信跳转到如下URL:
回调地址/?code=CODE&state=1

上面代码可以通过$_GET['code']获得一个CODE值,利用这个CODE值和appid,可以获得openid和access_token。
下面再用PHP来实现以下:

复制代码代码如下:
if($_GET['code']) {
  $code = $_GET['code'];
  $data = get_by_curl('https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSRC&code='.$code.'&grant_type=authorization_code');
  $data = json_decode($data);
  $openid = $data->openid;
  $access_token = $data->access_token;
}
function get_by_curl($url,$post = false){
    $ch = curl_init();
    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    if($post){
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$post);
    }
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

这样可以就可以获得openid和access_token,利用这些值,我们还可以利用微信公众平台的获取用户基本信息api接口获取用户基本信息。

希望本文所述对大家基于PHP的微信公众号开发有所帮助。


2018-10-05 23:43:52 qq_29914837 阅读数 654
  • 微信公众号开发5-自定义菜单-微信开发php

    微信公众平台开发之自定义菜单管理是子恒老师《微信公众平台开发》视频教程的第5部。详细讲解了用php开发微信,对微信公众平台中的自定义管理开发。内容包含微信添加菜单,获取自定义菜单配置,删除菜单等等。欢迎反馈,微信/QQ:68183131

    5686 人正在学习 去看看 秦子恒

自定义菜单删除接口

使用接口创建自定义菜单后,开发者还可使用接口删除当前使用的自定义菜单。另请注意,在个性化菜单时,调用此接口会删除默认菜单及全部个性化菜单。

请求说明

http请求方式:GET
https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN

返回说明

对应创建接口,正确的Json返回结果:

{"errcode":0,"errmsg":"ok"}

在这里插入图片描述

在这里插入图片描述

微信公众号开发

阅读数 48

没有更多推荐了,返回首页