• PHP实现微信公众号分享接口


    还是一贯风格:用代码说话!!!

     <?php
    
        class ShareModel extends BaseModel
        {
        var $appId = APPID;
        var $appSecret = APPSECRET;
    
        public function getJsApiTicket()
        {
              $ticket_file = '/dev/shm/jsapi_ticket.json';
              $data = json_decode(file_get_contents($ticket_file));
              if ($data->expire_time < time()) {
                  $accessToken = $this->getApiAccessToken();
                  $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
                  $res = json_decode($this->http_request($url));
                  $ticket = $res->ticket;
                  if ($ticket) {
                      $data->expire_time = time() + 7000;
                      $data->jsapi_ticket = $ticket;
                      file_put_contents($ticket_file, json_encode($data));
                  }
              } else {
                  $ticket = $data->jsapi_ticket;
              }
    
              return $ticket;
          }
    
    /*微信公众号,不需要获取用户信息:所以不需要授权,即使用appid、appsecret和grant_type换取access_token*/
    /*
    微信对于access_token的请求存在日请求数的限制 所以要全局缓存access_token,在过期时间内直接使用存的值;
    这里使用file_put_contents()代替fwrite()、fopen()、fclose();
     file_put_content()如果文件不存在就先创建文件这里要注意把缓存文件放/dev/shm/*下面,这个磁盘文件会在重启的时候清空数据,
    由于这个access_token丢失也不会存在问题,所以存在这里有助于减轻磁盘内存压力
    */
        
        private function getApiAccessToken()
        {
            $token_file = '/dev/shm/access_token.json';
            $data = json_decode(file_get_contents($token_file));
            if ($data->expire_time < time()) {
                $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret";
                $res = json_decode($this->http_request($url));
                $access_token = $res->access_token;
                if ($access_token) {
                    $data->expire_time = time() + 7000;
                    $data->access_token = $access_token;
                    file_put_contents($token_file, json_encode($data));
                }
            } else {
                $access_token = $data->access_token;
            }
            return $access_token;
        }
    
    
        //HTTP请求(支持HTTP/HTTPS,支持GET/POST)
        private function http_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, TRUE);
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            }
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
            $output = curl_exec($curl);
            curl_close($curl);
            file_put_contents('/tmp/weixin.' . date("Ymd") . '.log', date("Y-m-d H:i:s") . "	" . $output . "
    ", FILE_APPEND); //记录微信请求的相关日志,以用于排插错误
            return $output;
        }
    
    

    |调用方式:
    接收前端传过来的当前请求页的url

        public function getApiTicketAction()
        {
            $model = new ShareModel();
            $jsapiTicket = $model->getJsApiTicket();
            $url = $this->_req->getQuery('url',"");
            if(!$url){
                response::err_lack_param(); //做一个参数检测的判断
            }
            $timestamp = time();
            $nonceStr = $this->createNonceStr(); //构造一个随机数,用来生成签名的一部分
    
            $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url"; //签名算法先按照ascII码排序
            $signature = sha1($string);  //对排序好的字符串加密
            $signPackage = array(
                "appId"     => $model->appId,
                "nonceStr"  => $nonceStr,
                "timestamp" => $timestamp,
                "signature" => $signature,
            );
            response::result($signPackage); //返回数据给前端
        }
    
        private function createNonceStr($length = 16) { //生成随机16个字符的字符串
            $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            $str = "";
            for ($i = 0; $i < $length; $i++) {
                $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
            }
            return $str;
        }
    
    

    由于自己的无知,一开始使用fwrite()来写文件,而线上服务器又严格限制代码写文件,导致全局缓存access_token 无效,
    进而所有用户的转发请求都直接跑去请求微信端的接口 随着访问数的增加,最后请求数超过了微信的日限制最大值,最后导致接口被限制一天不能使用。
    这个要注意:做缓存的文件存放的服务器磁盘是否有读写权限。

  • 相关阅读:
    spring mvc EL ModelAndView的 Model 值 在jsp中不显示
    maven修改本地仓库,远程仓库与中央仓库
    Maven 手动添加 JAR 包到本地仓库
    Maven项目的结构分析
    Maven 构建配置文件
    SVN使用出现的问题及解决方案
    Eclipse中SVN的安装步骤(两种)和使用方法
    Eclipse SVN 使用教程
    svn使用教程总结
    eclipse下配置安装ssm图文教程(web版)
  • 原文地址:https://www.cnblogs.com/xinxinmifan/p/wechat_sharing.html
Copyright © 2020-2023  润新知