由于一直做各种对接工作,所以也总结了下常用的接口,适用于目前黄钻、蓝钻的页游对接,有兴趣的朋友可以来指点。


<?php/*** 腾讯接口统一API 此接口应该先调用init方法后再执行其他操作.即 QqApi::init($appid, $appkey, $server_name);*/
class QqApi {private static $sandbox = true;private static $appid       = 0;private static $appkey      = '';private static $server_name = '';private static $format      = 'json';private static $stat_url    = "apistat.tencentyun.com";CONST OPEN_API_TENCENTYUN      = 'openapi.tencentyun.com';CONST OPEN_API_TENCENTYUN_TEST = '119.147.19.43';CONST OPEN_API_GET_PFKEY = '113.108.20.23';// 腾讯PF常量CONST PID_TENCENT = 'tencent';CONST PF_QQGAME = 'qqgame';CONST PF_QZONE = 'qzone';CONST PF_WEBSITE = 'website';CONST PF_OPENAPP = 'qqopenapp';CONST PF_TGP = 'tgp';CONST PF_UNION = 'union';CONST PF_XINYUE = 'xinyue';// **************** 集市任务cmd码 ****************/*** 开发者仅需要查询任务步骤是否完成,返回步骤完成状态。*/CONST TASK_MARKET_CMD_CHECK = 'check';/*** 开发者需要查询任务步骤是否完成,若步骤已完成,直接给用户发货(payitem),并返回发货是否成功。*/CONST TASK_MARKET_CMD_CHECK_AWARD = 'check_award';/*** 平台通知开发者直接给给用户发货,开发者返回发货是否成功。*/CONST TASK_MARKET_CMD_AWARD = 'award';/*** 反馈给腾讯任务集市的状态码* !!沙箱联调时,ret返回码仅能返回0和3!!*//*** 步骤已完成 或 奖励发放成功*/CONST TASK_MARKET_RET_OK = 0;/*** 用户尚未在应用内创建角色*/CONST TASK_MARKET_RET_NO_ROLE = 1;/*** 用户尚未完成本步骤*/CONST TASK_MARKET_RET_NOT_FINISHED = 2;/*** 该步骤奖励已发放过*/CONST TASK_MARKET_RET_HAS_AWARDED = 3;/*** token已过期*/CONST TASK_MARKET_RET_TOKEN_EXPIRE = 100;/*** token不存在*/CONST TASK_MARKET_RET_TOKEN_NOT_FOUND = 101;/*** 奖励发放失败*/CONST TASK_MARKET_RET_AWARD_FAILS = 102;/*** 请求参数错误*/CONST TASK_MARKET_RET_PARAM_ERROR = 103;/*** 玩家信息*/CONST S_QQ_API_USER_INFO = '/v3/user/get_info';/*** 取得PFKEY*/CONST S_QQ_API_GET_PFKEY = '/v3/user/get_pfkey';/*** QQ API 蓝钻信息*/CONST S_QQ_API_BLUE_VIP = '/v3/user/blue_vip_info';/*** QQ API 黄钻信息*/CONST S_QQ_API_YELLOW_VIP = '/v3/user/is_vip';/*** QQ API 各类腾讯增值服务信息*/CONST S_QQ_API_TOTAL_VIP = '/v3/user/total_vip_info';/*** QQ API 心悦信息*/CONST S_QQ_API_XINYUE_INFO = '/v3/user/get_xinyue_info';/*** QQ API 是否登录*/CONST S_QQ_API_IS_LOGIN = '/v3/user/is_login';/*** QQ API 防沉迷接口*/CONST S_QQ_API_ANTIADDICTION_INFO = '/v3/user/get_antiaddiction_info';/*** QQ API 获取交易TOKEN*/CONST S_QQ_API_BUY_GOODS = '/v3/pay/buy_goods';/*** 取得包月礼包*/CONST S_QQ_API_GET_TOKEN = '/v3/pay/get_token';/*** 取得包月礼包token* 参考 http://wiki.open.qq.com/wiki/v3/pay/get_token* @param string $openid* @param string $openkey* @param string $pf* @param string $pfkey* @param string $discountid* @param int $tokentype* @param string $method* @param string $protocol* @return array*/static function getToken($openid, $openkey, $pf, $pfkey, $discountid, $tokentype=1, $method = 'GET', $protocol = 'http'){$params = array('openid'=>$openid,'openkey'=>$openkey,'pf'=>$pf,'pfkey'=>$pfkey,'tokentype'=>$tokentype,'ts'=>$_SERVER['REQUEST_TIME'],'discountid'=>$discountid,'zoneid'=>0,'version' => 'v3',);return self::api(self::S_QQ_API_GET_TOKEN, $params, $method, $protocol);}/*** 取得完整的联盟PF* @param string $appid* @param string $openid* @return string $pf*/static function unionPf($openid=''){$url = 'http://union.tencentlog.com/cgi-bin/Query.cgi?appid=' . self::$appid . '&opopenid=' . $openid;$ret = Utils::get($url, '', false);$ret = iconv('gb2312', 'utf-8', $ret);$result = json_decode($ret, 1);if ($result['iRet'] == 0) {return $result['sPf'];} else {return '';}}/*** 取得联盟的pfkey* @param string $openid* @param string $openkey* @param string $pf* @return string*/static function unionPfkey($openid, $openkey, $pf){$url = 'http://union.tencentlog.com/control/GetPfkey.php?app=' . self::$appid . '&pf=' . $pf . '&openid=' . $openid . '&openkey=' . $openkey;$ret = Utils::get($url, '', false);$ret = iconv('gb2312', 'utf-8', $ret);$result = json_decode($ret, 1);if ($result['ret'] == 0) {return $result['pfkey'];} else {return '';}}static function pfkey($openid, $openkey, $pf, $method = 'GET', $protocol = 'http'){$params = array('openid' => $openid,'openkey' => $openkey,'pf' => $pf,);/*** 返回值* ret      返回码 0 成功* pfkey* is_lost  忽略此值*/$ret = self::api(self::S_QQ_API_GET_PFKEY, $params, $method, $protocol, self::OPEN_API_GET_PFKEY);if ( $openid == '5A86F5B031580BBA67945EC315F78A4A'){var_dump($ret);}return $ret['pfkey'] ? : '';}CONST S_QQ_API_GET_PFKEY_BY_OPENID = 'http://apps.game.qq.com/wan/box/App/GetPfkeyByOpenid.php';/*** 根据OPENID取得pfkey* @param $openid* @param $openkey* @param $pf* @return array|mixed*/static function getPfkeyByOpenid($openid, $openkey, $pf){$params = array('appid'=>self::$appid,'openid'=>$openid,'openkey'=>$openkey,'pf'=>$pf,);$ret =  Utils::get(self::S_QQ_API_GET_PFKEY_BY_OPENID, $params, false);$ret = str_ireplace('var GetPfkeyByOpenid_JSON = ', '', $ret);$json = json_decode($ret, 1);if ( $json ){if ( $json['ret'] == 0 ){return $json['pfkey'];}}return '';}/*** 获取交易TOKEN* @param array $params 应该包含如下字段:*      pfkey:      必须*      amt:            交易总价 Q点为单位 1Q币=10Q点*      amttype:        支付方式:coin:仅允许使用游戏币支付,不传为Q点*      ts:         必须 时间戳*      payitem:    必须 ID*Price*Num,单价最少不能少于2Q点*      appmode:        购买数量类型 1:不可选 2:可选*      max_num:        购买数量上限 appmode:2时有效*      goodsmeta:  必须 商品描述信息 256字符内utf8编码*      goodsurl:   必须 商品图片URL 116x116px*      zoneid:     必须 分区ID,默认0*      manyouid:       视情况,详见文档*      present:        是否是礼物   0或不传给自己 1:送给好友 2:索要*      paymode:        忽略*      cee_extend:     忽略* @return array*/static function buyGoods($params=array()){/*** 参考 http://wiki.open.qq.com/wiki/v3/pay/buy_goods* ret          返回码* msg          错误信息* is_lost      是否有数据丢失(忽略此值)* token        ret=0时为临时订单号* url_params   ret=0时为真正购买物品的url参数,获取此值后传给前端有js唤起支付接口*/return self::api(self::S_QQ_API_BUY_GOODS, $params, 'post', 'https');}/*** 获得用户信息* @param string $openid* @param string $openkey* @param string $pf* @param string $pfkey* @param int $flag 当pf为蓝钻时,flag为要获取的数据类型。1:昵称性别 2:蓝钻等级 3:昵称和蓝钻等级 4:照片秀标识* @param string $method* @param string $protocol* @return array*/static function getUserInfo($openid, $openkey, $pf, $pfkey, $flag = 1, $method = 'GET', $protocol = 'http') {/*** 参考 http://wiki.open.qq.com/wiki/v3/user/get_info* ret 返回码* msg 错误信息* is_lost    判断是否有数据丢失。如果应用不使用cache,不需要关心此参数。 0或者不返回:没有数据丢失,可以缓存。 1:有部分数据丢失或错误,不要缓存。* nickname    昵称。* gender    性别。* country    国家(当pf=qzone、pengyou或qplus时返回)。* province    省(当pf=qzone、pengyou或qplus时返回)。* city    市(当pf=qzone、pengyou或qplus时返回)。* figureurl    头像URL。详见:前端页面规范#6. 关于用户头像的获取和尺寸说明。* openid    用户QQ号码转化得到的ID(当pf=qplus时返回)。* qq_level    用户QQ等级(当pf=qplus时返回)。* qq_vip_level    用户QQ会员等级(当pf=qplus时返回)。* qplus_level    用户Q+等级(当pf=qplus时返回)。* is_yellow_vip    是否为黄钻用户(0:不是; 1:是)。(当pf=qzone、pengyou或qplus时返回)* is_yellow_year_vip    是否为年费黄钻用户(0:不是; 1:是)。 (当pf=qzone、pengyou或qplus时返回)* yellow_vip_level    黄钻等级,目前最高级别为黄钻8级(如果是黄钻用户才返回此参数)。(当pf=qzone、pengyou或qplus时返回)* is_yellow_high_vip    是否为豪华版黄钻用户(0:不是; 1:是)。(当pf=qzone、pengyou或qplus时返回)* is_blue_vip    是否为蓝钻用户(0:不是; 1:是)。(当pf=qqgame或3366时返回)* is_blue_year_vip    是否为年费蓝钻用户(0:不是; 1:是)。(当pf=qqgame或3366时返回)* blue_vip_level    蓝钻等级(如果是蓝钻用户才返回此参数)。(当pf=qqgame或3366时返回)* 3366_level    3366用户的大等级。(当pf=3366时返回)* 3366_level_name    3366用户的等级名,如小游游、小游仙。(当pf=3366时返回)* 3366_grow_level    3366用户的成长等级。(当pf=3366时返回)* 3366_grow_value    3366用户的成长值。(当pf=3366时返回)* is_super_blue_vip    是否是豪华蓝钻。(当pf=qqgame或3366时返回)*/$params = array('openid' => $openid,'openkey' => $openkey,'pfkey' => $pfkey,'pf' => $pf,);if ('qqgame' == $pf) {$params['flag'] = $flag;}return self::api(self::S_QQ_API_USER_INFO, $params, $method, $protocol);}/*** 判断用户是否登录* @param string $openid* @param string $openkey* @param string $pf* @param string $pfkey* @param string $method* @param string $protocol* @return array*/static function isLogin($openid, $openkey, $pf, $pfkey, $method = 'GET', $protocol = 'http') {/*** 参考 http://wiki.open.qq.com/wiki/v3/user/is_login* ret 返回码* msg 错误信息*/return self::api(self::S_QQ_API_IS_LOGIN, array('openid' => $openid,'openkey' => $openkey,'pfkey' => $pfkey,'pf' => $pf,), $method, $protocol);}/*** 获得防沉迷信息* @param string $openid* @param string $openkey* @param string $pf* @param string $pfkey* @param int $cmd_type* @param string $method* @param string $protocol*/static function getAntiaddiction($openid, $openkey, $pf, $pfkey, $cmd_type = 2, $method = 'GET', $protocol = 'http') {/*** 参考 http://open.qqgame.qq.com/inside/lodyapi/get_antiaddiction_info.htm* ret      返回码* msg      错误描述* audit    身份信息: 0:未成年 1:成年 2:无身份证验证(1时gametime无意义)* gametime 在线时长*/return self::api(self::S_QQ_API_IS_LOGIN, array('openid' => $openid,'openkey' => $openkey,'pfkey' => $pfkey,'pf' => $pf,'cmd_type' => $cmd_type,), $method, $protocol);}/*** 检测蓝钻状态* @param string $openid* @param string $openkey* @param string $pf* @param string $pfkey* @return mixed*/static function isBlueVip($openid, $openkey, $pf, $pfkey, $method = 'GET', $protocol = 'http') {/*** 此接口返回值*  is_blue_vip int 是否蓝钻, 1 表示是,0 表示不是*  is_blue_year_vip int 是否年费蓝钻;1 表示是,0 表示不是*  is_super_blue_vip int 是否豪华蓝钻;1 表示是,0 表示不是*  is_expand_blue_vip int 是否超级蓝钻;1 表示是,0 表示不是*  blue_vip_level int 蓝钻等级*  is_have_growth int 蓝钻是否具备成长值,1 表示是,0 表示不是*  is_mobile_blue_vip int 是否手机蓝钻;1 表示是,0 表示不是*  server_time int 服务器时间,用于比较蓝钻开通时间和到期时间,unix 时间戳,单位为秒*  vip_reg_time int 蓝钻开通时间,unix 时间戳,单位为秒*  year_vip_reg_time int 年费蓝钻开通时间,unix 时间戳,单位为秒*  super_vip_reg_time int 豪华蓝钻开通时间,unix 时间戳,单位为秒*  expand_vip_reg_time int 超级蓝钻开通时间,unix 时间戳,单位为秒*  vip_valid_time int 蓝钻到期时间,unix 时间戳,单位为秒*  year_vip_valid_time int 年费蓝钻到期时间,unix 时间戳,单位为秒*  super_vip_valid_time int 豪华蓝钻到期时间,unix 时间戳,单位为秒*  expand_vip_valid_time int 超级蓝钻到期时间,unix 时间戳,单位为秒*/return self::api(self::S_QQ_API_BLUE_VIP, array('openid' => $openid,'openkey' => $openkey,'pfkey' => $pfkey,'pf' => $pf,), $method, $protocol);}/*** 检测黄钻状态* @param string $openid* @param string $openkey* @param string $pf* @param string $pfkey* @return mixed*/static function isYellowVip($openid, $openkey, $pf, $pfkey, $method = 'GET', $protocol = 'http') {/*** 此接口返回值 http://wiki.open.qq.com/wiki/v3/user/is_vip* ret 返回码* msg 消息* is_lost                1:有部分数据丢失或错误,不要缓存。* is_yellow_vip          是否为黄钻用户(0:不是; 1:是)* is_yellow_year_vip     是否为年费黄钻用户(0:不是; 1:是)* yellow_vip_level       黄钻等级。目前最高级别为黄钻8级(如果是黄钻用户才返回此字段)* is_yellow_high_vip     是否为豪华版黄钻用户(0:不是; 1:是)。(当pf=qzone、pengyou或qplus时返回)* yellow_vip_pay_way     用户的付费类型。0:非预付费用户(先开通业务后付费,一般指通过手机开通黄钻的用户);1:预付费用户(先付费后开通业务,一般指通过Q币Q点、财付通或网银付费开通黄钻的用户)。*/return self::api(self::S_QQ_API_YELLOW_VIP, array('openid' => $openid,'openkey' => $openkey,'pfkey' => $pfkey,'pf' => $pf,), $method, $protocol);}/*** 返回是否心悦用户* @param string $openid* @param string $openkey* @param string $pf* @param string $pfkey* @param string $method* @param string $protocol* @return array*/static function isXinyue($openid, $openkey, $pf, $pfkey, $method = 'GET', $protocol = 'http') {/*** 心悦接口:非普通API* xy_type: 心悦会员类型,1为普通心悦,2为蓝悦,3为财悦(目前暂时只支持1)。* xy_level: 心悦会员等级。*/return self::api(self::S_QQ_API_XINYUE_INFO, array('openid' => $openid,'openkey' => $openkey,'pfkey' => $pfkey,'pf' => $pf,), $method, $protocol);}/*** 返回腾讯所有VIP信息* @param string $openid* @param string $openkey* @param string $pf* @param string $pfkey* @param string $method* @param string $protocol* @return array*/static function totalVIP($openid, $openkey, $pf, $pfkey, $method = 'GET', $protocol = 'http') {/*** 参考 http://wiki.open.qq.com/wiki/v3/user/total_vip_info* member_vip    string    是否查询QQ会员信息,1为查询,0或者不写为不查询。* blue_vip        string    是否查询蓝钻信息,1为查询,0或者不写为不查询。* yellow_vip    string    是否查询黄钻信息,1为查询,0或者不写为不查询。* red_vip        string    是否查询红钻信息,1为查询,0或者不写为不查询。* green_vip    string    是否查询绿钻信息,1为查询,0或者不写为不查询。* pink_vip        string    是否查询粉钻信息,1为查询,0或者不写为不查询。* superqq        string    是否查询超级qq信息,1为查询,0或者不写为不查询。* is_3366        string    是否查询3366信息,1为查询,0或者不写为不查询。*/return self::api(self::S_QQ_API_TOTAL_VIP, array('openid' => $openid,'openkey' => $openkey,'pfkey' => $pfkey,'pf' => $pf,), $method, $protocol);}/*** 初始化QQApi(必须在调用本类其他方法前调用)** @param int $appid 应用的ID* @param string $appkey 应用的密钥* @param bool $sandbox 服务器ID*/static function init($appid, $appkey, $sandbox = false) {self::$appid  = $appid;self::$appkey = $appkey;self::isSandbox($sandbox);}/*** 设置服务器域名(并不考虑$debug值)* @param $server_name*/static function setServerName($server_name) {return self::$server_name = $server_name;}static function setStatUrl($stat_url) {self::$stat_url = $stat_url;}/*** 设置调试模式(设置后URL也会根据$debug值判断)* @param bool $debug* @return bool*/static function isSandbox($debug = false) {self::$sandbox       = $debug;self::$server_name = !!self::$sandbox ? self::OPEN_API_TENCENTYUN_TEST : self::OPEN_API_TENCENTYUN;return self::$sandbox;}CONST S_QQ_API_CONFIRM_DELIVERY = '/v3/pay/confirm_delivery';/*** 提交反馈信息* @param array $params* @param string $method* @param string $protocol* @return array*/static function confirmDelivery($params=array(), $method = 'GET', $protocol = 'http'){$params = array('openid'=>$params['openid'],'pf'=>$params['pf'],'ts' => $params['openid'],'payitem' => $params['payitemde'],'provide_errno' => 0,'token_id' => $params['token_id'],'billno' => $params['billno'],'amt' => $params['amt'],'payamt_coins' => $params['payamt_coins'],'providetype'=>0,'zoneid' => $params['zoneid'] ? : 0,);//file_put_contents('/tmp/order_delivery.txt', print_r($params, 1)."\r\n".self::$appid.'-'.self::$appkey.'-'.self::$sandbox."\r\n", FILE_APPEND);return self::api(self::S_QQ_API_CONFIRM_DELIVERY, $params, $method, $protocol);}/*** 执行API调用,返回结果数组** @param string $script_name 调用的API方法,比如/v3/user/get_info,参考 http://wiki.open.qq.com/wiki/API_V3.0%E6%96%87%E6%A1%A3* @param array $params 调用API时带的参数* @param string $method 请求方法 post / get* @param string $protocol 协议类型 http / https* @return array 结果数组*/static function api($script_name, $params, $method = 'post', $protocol = 'http', $server_name='') {// 检查 openid 是否为空if (!isset($params['openid']) || empty($params['openid'])) {return array('ret' => 'OPENAPI_ERROR_REQUIRED_PARAMETER_EMPTY','msg' => 'openid is empty');}// 检查 openid 是否合法if (!self::isOpenId($params['openid'])) {return array('ret' => 'OPENAPI_ERROR_REQUIRED_PARAMETER_INVALID','msg' => 'openid is invalid');}// 无需传sig, 会自动生成unset($params['sig']);// 添加一些参数$params['appid']  = self::$appid;$params['format'] = self::$format;// 生成签名$secret        = self::$appkey . '&';$sig           = self::makeSig($method, $script_name, $params, $secret);$params['sig'] = $sig;$url    = $protocol . '://' .( $server_name ? : self::$server_name ). $script_name;$cookie = array();//记录接口调用开始时间$start_time = self::getTime();// 发起请求$ret = self::makeRequest($url, $params, $cookie, $method, $protocol);if (false === $ret['result']) {return array('ret' => 'OPENAPI_ERROR_CURL ' . +$ret['errno'],'msg' => $ret['msg'],);}$result_array = json_decode($ret['msg'], true);// 远程返回的不是 json 格式, 说明返回包有问题if (is_null($result_array)) {$result_array = array('ret' => 'OPENAPI_ERROR_RESPONSE_DATA_INVALID','msg' => $ret['msg']);}return $result_array;}static public function getTime() {list($usec, $sec) = explode(" ", microtime());return ((float)$usec + (float)$sec);}/*** 检查 openid 的格式** @param string $openid openid* @return bool (true|false)*/static private function isOpenId($openid) {return preg_match('/^[0-9a-fA-F]{32}$/i', $openid);}/*** 执行一个 HTTP 请求** @param string $url 执行请求的URL* @param mixed $params 表单参数*                            可以是array, 也可以是经过url编码之后的string* @param mixed $cookie cookie参数*                            可以是array, 也可以是经过拼接的string* @param string $method 请求方法 post / get* @param string $protocol http协议类型 http / https* @return array 结果数组*/static public function makeRequest($url, $params, $cookie, $method = 'post', $protocol = 'http') {$query_string  = self::makeQueryString($params);$cookie_string = self::makeCookieString($cookie);$ch = curl_init();if ('GET' == strtoupper($method)) {curl_setopt($ch, CURLOPT_URL, "$url?$query_string");} else {curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);}curl_setopt($ch, CURLOPT_HEADER, false);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);// disable 100-continuecurl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));if (!empty($cookie_string)) {curl_setopt($ch, CURLOPT_COOKIE, $cookie_string);}if ('https' == $protocol) {curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);}$ret = curl_exec($ch);$err = curl_error($ch);if (false === $ret || !empty($err)) {$errno = curl_errno($ch);$info  = curl_getinfo($ch);curl_close($ch);return array('result' => false,'errno' => $errno,'msg' => $err,'info' => $info,);}curl_close($ch);return array('result' => true,'msg' => $ret,);}/*** 执行一个 HTTP 请求,以post方式,multipart/form-data的编码类型上传文件** @param string $url 执行请求的URL* @param mixed $params 表单参数,必须是array, 对于文件表单项 直接传递文件的全路径, 并在前面增加'@'符号*                          举例: array('upload_file'=>'@/home/xxx/hello.jpg', 'field1'=>'value1');* @param mixed $cookie cookie参数*                            可以是array, 也可以是经过拼接的string* @param string $protocol http协议类型 http / https* @return array 结果数组*/static public function makeRequestWithFile($url, $params, $cookie, $protocol = 'http') {$cookie_string = self::makeCookieString($cookie);$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_POSTFIELDS, $params);curl_setopt($ch, CURLOPT_HEADER, false);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);// disable 100-continuecurl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));if (!empty($cookie_string)) {curl_setopt($ch, CURLOPT_COOKIE, $cookie_string);}if ('https' == $protocol) {curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);}$ret = curl_exec($ch);$err = curl_error($ch);if (false === $ret || !empty($err)) {$errno = curl_errno($ch);$info  = curl_getinfo($ch);curl_close($ch);return array('result' => false,'errno' => $errno,'msg' => $err,'info' => $info,);}curl_close($ch);return array('result' => true,'msg' => $ret,);}static public function makeQueryString($params) {if (is_string($params))return $params;$query_string = array();foreach ($params as $key => $value) {array_push($query_string, rawurlencode($key) . '=' . rawurlencode($value));}$query_string = join('&', $query_string);return $query_string;}static public function makeCookieString($params) {if (is_string($params))return $params;$cookie_string = array();foreach ($params as $key => $value) {array_push($cookie_string, $key . '=' . $value);}$cookie_string = join('; ', $cookie_string);return $cookie_string;}/*** 生成签名** @param string $method 请求方法 "get" or "post"* @param string $url_path* @param array $params 表单参数* @param string $secret 密钥*/static public function makeSig($method, $url_path, $params, $secret) {$mk      = self::makeSource($method, $url_path, $params);$my_sign = hash_hmac("sha1", $mk, strtr($secret, '-_', '+/'), true);$my_sign = base64_encode($my_sign);return $my_sign;}static private function makeSource($method, $url_path, $params) {$strs = strtoupper($method) . '&' . rawurlencode($url_path) . '&';ksort($params);$query_string = array();foreach ($params as $key => $val) {array_push($query_string, $key . '=' . $val);}$query_string = join('&', $query_string);return $strs . str_replace('~', '%7E', rawurlencode($query_string));}/*** 验证回调发货URL的签名 (注意和普通的OpenAPI签名算法不一样,详见@refer的说明)** @param string $method 请求方法 "get" or "post"* @param string $url_path* @param array $params 腾讯调用发货回调URL携带的请求参数* @param string $secret 密钥* @param string $sig 腾讯调用发货回调URL时传递的签名** @refer*  http://wiki.open.qq.com/wiki/%E5%9B%9E%E8%B0%83%E5%8F%91%E8%B4%A7URL%E7%9A%84%E5%8D%8F%E8%AE%AE%E8%AF%B4%E6%98%8E_V3*/static public function verifySig($method, $url_path, $params, $secret, $sig) {unset($params['sig']);// 先使用专用的编码规则对value编码foreach ($params as $k => $v) {$params[$k] = self::encodeValue($v);}// 再计算签名$sig_new = self::makeSig($method, $url_path, $params, $secret);return $sig_new == $sig;}/*** 回调发货URL专用的编码算法*  编码规则为:除了 0~9 a~z A~Z !*()之外其他字符按其ASCII码的十六进制加%进行表示,例如"-"编码为"%2D"* @refer*  http://wiki.open.qq.com/wiki/%E5%9B%9E%E8%B0%83%E5%8F%91%E8%B4%A7URL%E7%9A%84%E5%8D%8F%E8%AE%AE%E8%AF%B4%E6%98%8E_V3*/static private function encodeValue($value) {$rst = '';$len = strlen($value);for ($i = 0; $i < $len; $i++) {$c = $value[$i];if (preg_match("/[a-zA-Z0-9!\(\)*]{1,1}/", $c)) {$rst .= $c;} else {$rst .= ("%" . sprintf("%02X", ord($c)));}}return $rst;}public function market($params, $method = 'get') {echo '<pre>';var_dump($params);echo '<br><br>';echo $sig = $params['sig'];$url_path = '/qqjz/Market';//$url_path = '/cgi-bin/check_award';unset($params['sig']);//验证用unset($params['app_user_source']);//unset($params['app_contract_id']);//unset($params['app_custom']);//echo '<br>';// 生成签名echo $secret = $this->appkey . '&';//$secret = '111222333'. '&';$strs = strtoupper($method) . '&' . rawurlencode($url_path) . '&';ksort($params);$query_string = array();foreach ($params as $key => $val) {$value = self::encodeValue($val);array_push($query_string, $key . '=' . $value);}$query_string = join('&', $query_string);//var_dump($query_string);//echo $newGet = $strs . str_replace('~', '%7E', rawurlencode($query_string));$my_sign = hash_hmac("sha1", $newGet, strtr($secret, '-_', '+/'), true);echo $my_sign = base64_encode($my_sign);die;}// *********** QQ罗盘上报相关 *********** //// QQ罗盘上报相关/*** QQ 罗盘上报地址-充值*/const QQ_COMPASS_URL_REPORT_CHARGE = 'http://tencentlog.com/stat/report_recharge.php';/*** QQ 罗盘上报地址-主动注册登录*/const QQ_COMPASS_URL_REPORT_REGISTER = 'http://tencentlog.com/stat/report_register.php';/*** 支付充值:用户通过Q点/Q币兑换游戏内等值货币(例如“点券/金币/元宝”)的行为。* 必填字段:* @param int $modifyfee 如果没有变化,则填0, 上报单位为Q分(100Q分 = 10Q点 = 1Q币))* 推荐项:* $touid, toopenid, source, itemid, itemtype, itemcnt, modifyexp, totalexp, modifycoin, totalcoin, totalfee, level*/public function reportCharge($opuid, $opopenid, $gold = 0, $domain = 1) {// 必填项目return self::compassReport($opuid, $opopenid, 2, array('modifyfee'), $gold, $domain);}/*** 默认的构建接口* 必选:* @param string $version 若未上报,则自动补齐为:1* @param string $appid 应用ID* @param string $userip 若未上报,则自动补齐为:http请求头里的客户机ip* @param string $svrip 若未上报,则自动补齐为:该cgi所在server的ip* @param int $time 若未上报,则自动补齐为:服务器当前时间* @param string $domain 域* @param string $worldid 若未上报,则自动补齐为:1* @param string $opuid* @param string $opopenid*/static function compassReport($opuid, $opopenid, $report_flag = 1, $params = array(), $gold=0, $domain=1){$req = Yii::app()->request;// 必填项目$version = $req->getParam('version'); // 由调用接口传$appid = self::$appid; // 由调用接口传$userip = $req->userHostAddress;$svrip = $req->getParam('srvip'); // 由调用接口传$time = time();$worldid = $req->getParam('worldid'); // 由调用接口传
//        $opuid = $req->getParam('opuid'); // 由调用接口传
//        $opopenid = $req->getParam('opopenid');// 构建默认必选参数表$params_str = <<<EOT
version={$version}&appid={$appid}&userip={$userip}&svrip={$svrip}&time={$time}&domain={$domain}&worldid={$worldid}&opuid={$opuid}&opopenid={$opopenid}
EOT;// 构造附加字段foreach ($params as $v) {$tmp_v = $req->getParam($v);if ($tmp_v) {$params_str .= "&{$v}=" . $tmp_v;}}$params_str.="&modifyfee=$gold";switch ($report_flag) {case 1:$url = self::QQ_COMPASS_URL_REPORT_REGISTER;break;case 2:$url = self::QQ_COMPASS_URL_REPORT_CHARGE;break;default:$url = '';}if ( $url ) {file_put_contents('/tmp/compass.txt', $url.'?'.$params);return Utils::get($url, $params_str, false);}return 0;}// *********** open.qq.com 服务器列表获取工具 *********** ///*** 取得腾讯开平的服务器配置* @return mixed*/static function getServerlist() {$cacheKey = '__CACHE_OPEN_QQ_SERVER_LIST__'.self::$appid;$data = Cache::cache_get($cacheKey);if ( !$data || BOSS_NO_CACHE){$str       = Utils::get('http://openwebgame.qq.com/app/RecentServerInfo.php?appid=' . self::$appid, null, false);$str = str_replace('var user_all_servers = ', '', $str);$tmp_array = explode('var user_recent_servers', $str);$str = str_replace(';', '', $tmp_array[0]);
//             处理服务器列表去掉历史记录$data = json_decode($str, 1);// 给一个300秒的缓存Cache::cache_set($cacheKey, $data, 300);}return $data;}/*** 取得推荐服列表* @return mixed*/static function getRecommendServers(){$cacheKey = $cacheKey = '__CACHE_OPEN_QQ_SERVER_RECOMMEND__'.self::$appid;$recommends = Cache::cache_get($cacheKey);if ( !$recommends || BOSS_NO_CACHE){$data = self::getServerlist();if (empty($data) || !is_array($data)){return $recommends;}$recommends = array();$lastServer = null;foreach($data as $zone){if ( empty($zone['subcat'])){continue;}foreach($zone['subcat'] as $srv){if ( $srv['sAttrValue']['iIsRecommend'] > 0 ){$recommends[] = $srv;}if ( !$lastServer )$lastServer = $srv;}}if ( count($recommends) > 0 ){// 找到1个以上的推荐服就缓存300秒Cache::cache_set($cacheKey, $recommends, 300);} else if ( $lastServer ){// 不存在推荐服时就取得一个最新的服务器, 即openqq服务器列表中最上面的那个服$recommends[] = $lastServer;Cache::cache_set($cacheKey, $recommends, 60);} else {// 尚未添加任意服务器也要缓存5秒防刷Cache::cache_set($cacheKey, $recommends, 5);}}return $recommends;}
}

来一个腾讯开平的工具类相关推荐

  1. java图片缩放工具类,一个JAVA图形缩放处置工具类

    一个JAVA图形缩放处理工具类 调用的例子 import java.io.FileOutputStream; import java.io.IOException; import javax.imag ...

  2. 基于Dapper二次封装了一个易用的ORM工具类:SqlDapperUtil

    基于Dapper二次封装了一个易用的ORM工具类:SqlDapperUtil,把日常能用到的各种CRUD都进行了简化封装,让普通程序员只需关注业务即可,因为非常简单,故直接贴源代码,大家若需使用可以直 ...

  3. 微服务应用大行其道,我提供一个dto和entity转换工具类,方便大家做转换,少写机械代码,多陪陪家人

    微服务应用大行其道,我提供一个dto和entity转换工具类,方便大家做转换,少写机械代码,多陪陪家人. 该工具类主要是对dozer进行了封装,使用过程代码量极少,废话少说,贴代码了 import j ...

  4. 微服务应用大行其道,我提供一个dto和entity转换工具类,方便大家做转换,少写机械代码,多陪陪家人...

    微服务应用大行其道,我提供一个dto和entity转换工具类,方便大家做转换,少写机械代码,多陪陪家人. 该工具类主要是对dozer进行了封装,使用过程代码量极少,废话少说,贴代码了 import j ...

  5. 分享一个发送http请求的工具类

    分享一个发送http请求的工具类 maven依赖只需要导入一个 <dependencies><dependency><groupId>commons-httpcli ...

  6. Druid+Sqlite-JDBC+Kotlin,封装的一个都是毛病的工具类,奆佬们,评论区教一下我怎么封装

    Druid+JDBC工具类 我只是一个新手,也不怎么会kotlin但是我看教程都很少,讲SQLite-JDBC结合Druid或者说怎么写Durid的配置文件, 我先放工具类 import com.al ...

  7. 一个java随机数据的工具类

    获得随机数据工具类 在一些业务还有测试中可能需要一些有实际意义的测试数据,编写这些数据可能比较头大,这里写了一个随机数据的工具类,具有以下功能: 获得指定长度的随机大写.小写.数字字母 获得随机的性别 ...

  8. C# 一个操作Oracle的简易工具类(通过System.Data.OracleClient)

    2019独角兽企业重金招聘Python工程师标准>>> 一.关于本文 运行本文中的代码,需要 1)需要手动添加引用System.Data.OracleClient 在代码最前面加入这 ...

  9. android 网络图片工具类,分享一个Android图片模糊的工具类

    图片模糊,试过很多工具什么的,还是这个类比较好,直接用就好了 使用方法: imageView.setImageBitmap(BlurUtil.doBlur(drawable,10,15)); pack ...

最新文章

  1. Linux下编辑器vi/vim的使用介绍
  2. 如何实现在H5里调起高德地图APP?(下)
  3. linux ls错误,ls错误
  4. python基础题面试_python常见面试题
  5. linux行位换行符,换行符或标点符号作为elasticsearch中的位置间隔
  6. 奔跑吧火柴人c语言开发_小学数学智力题:这两个火柴棍趣味题,你能做出来吗?...
  7. CVE-2020-16875: Microsoft Exchange远程代码执行漏洞通告
  8. 正在爆发的互联网革命
  9. 阿里云短信发送 错误 请检查模板内容与模板参数是否匹配
  10. java格林威治时间转换_JAVA 格式化格林威治时间(Wed Aug 01 00:00:00 CST 2012)格式转换...
  11. vgp虚拟路面_吉水县道路运输展示价格实惠
  12. 简单有效的通过js使用qrcode扫描二维码
  13. 网络安全初创企业Illumio融资1.25亿美元 摩根领投
  14. mysql第五次作业 查询数据
  15. 运动员和教练(接口实现)
  16. rust python_用于Python程序员的Rust
  17. 2019、2020、2021年技术知识巩固记录
  18. 菜鸟成长记----做一个简易的搜索引擎
  19. CapsuleRRT: Relationships-aware Regression Tracking via Capsules
  20. Windows系统删除并改为Centos8.X系统

热门文章

  1. 苹果手机系统是linux吗,全面解析为何苹果手机比安卓手机流畅稳定
  2. 韶关实验室设计要点汇总
  3. 微信小程序循环列表实现单个显示与隐藏
  4. maya如何查看资源大纲_“大纲视图”(Outliner)上下文菜单
  5. vs2008 自动化编译工程(devenv.com)
  6. SECURITY 服务安全与监控/su/sudo/
  7. 计算机设置的用户磁盘访问权限,有关映射网络驱动硬盘权限的设置。
  8. 2016春季APP实力榜: 高德地图增长率排前三
  9. 计算机老师老师的发展前进,描写教师的优美句子 将永远激励着我人生前进的脚步...
  10. ubuntu上播放PCM音频