1. 程式人生 > >微信呼叫介面,防止Access_token過期的方法

微信呼叫介面,防止Access_token過期的方法

        //得到訂閱使用者 (返回陣列)
	public function GetUserList()
	{
		$strjson = $this -> GetUrlReturn("https://api.weixin.qq.com/cgi-bin/user/get?access_token=%s");
		$openidarr= $strjson->data->openid;
		//print_r($openidarr); 除錯
		return $openidarr;
	}
	
	//得到訂閱使用者詳情(返回物件)
	public function GetUserDetail($openid)
	{
		$url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid={$openid}";
		$strjson = $this -> GetUrlReturn($url);
		return $strjson;
	}
	
	
	/*
	*
	*  私有成員變數 存token值
	*  因為//access_token是公眾號的全域性唯一票據,公眾號呼叫各介面時都需使用access_token。
	*  正常情況下access_token有效期為7200秒,重複獲取將導致上次獲取的access_token失效。
	*/
	private $_token ;

	/*
	*
	* 私有方法
	*
	*/
	//得到Token物件並寫入到配置檔案
	private function InitToken()
	{
		$url = sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",APPID, SECRET);
		//echo APPID;
		$ch = curl_init(); //建立一個新url資源
		curl_setopt($ch, CURLOPT_URL,$url);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		$a = curl_exec($ch);
		$strjson=json_decode($a);
		$token = $strjson->access_token;
		if (empty($token))
		{
			//修改 {"errcode":45009,"errmsg":"api freq out of limit"}
			echo "錯誤:取得token無效,可能是呼叫太頻繁!";	  //$strjson
			throw new Exception('錯誤:取得token無效'); 
		}
		
		$obj = fopen("saestor://weixindata/token.txt","w+");  //SAE禁用fopen本地檔案,這裡需要Storage
		fwrite($obj,$token);
		$this -> _token = $token;
	}
	
	//封裝私有方法,呼叫得到Get的引數,$needToken預設為false, 不取值,這裡有一個潛規則,%s為 self::$_token
	private function GetUrlReturn($url, $needToken = false)
	{
		//第一次為空,則從檔案中讀取
		if (empty($this -> _token))
		{
			$obj = fopen("saestor://weixindata/token.txt","r"); 
			$this -> _token = fgets($obj,1000);
		}
		
		//為空則重新取值
		if (empty($this -> _token) || $needToken)
		{
			$this ->InitToken(); 
		}
		$newurl = sprintf($url, $this -> _token);
		$ch = curl_init();  //建立一個新url資源
		curl_setopt($ch, CURLOPT_URL,$newurl);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		$a = curl_exec($ch);
		$strjson=json_decode($a);
		//var_dump($strjson);  //開啟可除錯
		if (!empty($strjson-> errcode))
		{
			switch ($strjson-> errcode){
				
				case 40001:
					$this -> GetUrlReturn($url, true); //重新取值,可能是過期導致
					break;
				case 41001:
					throw new Exception("缺少access_token引數:".$strjson->errmsg); 
					break;
				default:
					throw new Exception($strjson->errmsg); //其他錯誤,丟擲
					break;
				
			}
		}
		return $strjson;
	}
大概意思是,預設就是從文字檔案中取這個值,當這個值過期的時候,重新呼叫 InitToken 這個方法,獲得最新的AccessToken。這樣AccessToken就永遠不會過期了。