当前位置:首页 > PHP教程 > PHP常见问题

详解使用php调用微信接口上传永久素材

功能需求

公司新开的公众号需要将公司平台现在的所有精品文章都导入,手动导入会有很多的工作量,所以采用自动化同步文章的方式来达到效果

开发说明

微信open api提供了新增永久素材的接口,本次功能是基于这个接口进行数据同步的

使用到的接口

  • 获取永久素材列表接口:material/batchget_material
  • 新增永久素材接口:material/add_news
  • 新增媒体文件接口:material/add_material
  • 图文类型
  • 单图文(要求有默认的封面,需要提前上传到微信公众号后台)
  • 环境要求

    php版本:5.5以下(因为下面代码中的上传媒体文件必须要求在此环境,否则会调用微信接口失败)

    开发流程

    1、从公司平台获取所有的文章列表
    2、遍历文章列表,查看文章是否有图片附件,若有进行第三步,否则进行第四步
    3、检测所有的附件,取出第一个图片附件,并调用新增媒体文件接口上传图片获得返回后的media_id
    4、调用素材列表接口获取默认的封面图片,并从中得到的数据中获取media_id
    5、根据返回获取到的media_id开始调用上传图文接口上传素材
    6、记录返回信息

    接口设计

    获取微信素材列表接口

    此接口是用于获取默认的图片media_id同步平台数据接口

    此接口是用户同步我们自己的文章数据到微信功能实现

    接口常量

    private $app_id = 'wx189ae9fa8816b131';
    private $app_secret = '36f5f430c591acbae3505fe877733283';
    const api_url_prefix = 'https://api.weixin.qq.com/cgi-bin';
    const media_forever_upload_url = '/material/add_material?';
    const media_forever_news_upload_url = '/material/add_news?';
    const media_forever_news_update_url = '/material/update_news?';
    const media_forever_get_url = '/material/get_material?';
    const media_forever_del_url = '/material/del_material?';
    const media_forever_count_url = '/material/get_materialcount?';
    const media_forever_batchget_url = '/material/batchget_material?';

    获取微信素材列表接口

    action接口方法

    说明:该方法为此接口的入口方法

    调用方式:http://${domain}/weixin/get_articles/

     /**
       * 获取图片素材接口
       */
      public function get_articles_action(){
       $token = $this->get_access_token();
       $list = $this->getforeverlist($token,'image',0,20);
       echo json_encode($list);
      }
      get_access_token方法
      
      private function get_access_token() {
       $access_token = aws_app::cache()->get('access_token');
       if(!$access_token){
        error_log('get access_token from weixin ');
        $appid = $this->app_id;
        $appsecret = $this->app_secret;
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret";
        $res = json_decode($this -> httpget($url));
        $access_token = $res -> access_token;
        aws_app::cache()->set('access_token',$access_token,time()+3600);
       }else{
        error_log('get access_token from cache ');
       }
       error_log('access_token is :'.$access_token);
       return $access_token;
      }
    

    调用微信素材接口方法

    说明:该方法为调用微信获取永久素材列表接口方法

     /**
      * 获取永久素材列表
      * @param $token
      * @param $type 类型有image,vedio和audio
      * @param $offset 起始位置,0表示从第一个
      * @param $count 个数,区间为0~20
      */
      public function getforeverlist($token,$type,$offset,$count){
       $data = array(
        'type' => $type,
        'offset' => $offset,
        'count' => $count,
       );
       $result = $this->http_post(
             self::api_url_prefix.self::media_forever_batchget_url.'access_token='.$token,
             self::json_encode($data)
             );
       error_log('forever list is :'.$result);
       if ($result)
       {
        $json = json_decode($result,true);
        if (isset($json['errcode'])) {
        $this->errcode = $json['errcode'];
        $this->errmsg = $json['errmsg'];
        return false;
        }
        return $json;
       }
       return false;
      }
    

    同步文章到微信接口

    action方法

    说明:该方法为此接口的入口方法

    调用方式:http://${domain}/weixin/upload_article/

    /**
     * 同步问答的文章到订阅号上接口
     */
    public function index_action(){
     $article_list = $this->model('article')->get_articles_list(null, 1, 18, 'add_time desc');
     $access_token = $this->get_access_token();
     $base_url = 'http://wenda.qiezilife.com/article/';
     foreach ($article_list as $key => $article){
    
      if($article['has_attach']){
       $attaches = $this->model('publish')->get_attach('article', $article['id'], 'max');
       foreach ($attaches as $i => $a){
        //过滤获取第一张图片
        if($a['is_image']){
         $attache = $a;
         break;
        }
       }
    
       $img = $attache['path'];
       $size = filesize($img);
       echo $img.',size is :'.$size;
       echo '<br/>';
       $file_info = array(
        'filename' => $img,
        'content-type' => 'image/jpg', //文件类型
        'filelength' => $size
       );
       $upload_img_result = $this->upload_meterial($file_info,$access_token);
       $media_id = $upload_img_result;
       error_log('media_id is ===============>'.$media_id);
      }else{
       $media_id = '1potp0sqruwwu_hx0hr_jup4stx5hspykibb1ca8zqa';
      }
    
      $articles =array();
      //上传图片成功了就开始上传图文
      $upload_article_data = array(
       'title' => $article['title'],
       'thumb_media_id' => $media_id,
       'author' => '茄子营养师',
       'digest' => '茄子生活,你的品质生活指南',
       'show_cover_pic' => 1,
       'content' => $article['message'],
       'content_source_url' => $base_url.$article['id']
      );
    
      $articles[] = $upload_article_data;
    
      $data = array(
       'articles' => $articles
      );
      $result= $this->uploadforeverarticles($access_token,$data);
      echo self::json_encode($result);
      error_log('upload_article result is : '.json_encode($result));
      error_log('============================upload end============================');
    
      }
    }
    
    

    uploadforeverarticles方法

    说明:该方法为调用微信上传永久素材接口方法

    /**
     * 上传永久图文素材(认证后的订阅号可用)
     * 新增的永久素材也可以在公众平台官网素材管理模块中看到
     * @param array $data 消息结构{"articles":[{...}]}
     * @return boolean|array
     */
    public function uploadforeverarticles($access_token,$data){
     error_log('post data is=======> '.self::json_encode($data));
     $url = self::api_url_prefix.self::media_forever_news_upload_url.'access_token='.$access_token;
     $result = http::request($url, 'post', self::json_encode($data));
     error_log('weixin return result is =====>'.$result);
     if ($result)
     {
      $json = json_decode($result,true);
      if (!$json || !empty($json['errcode'])) {
       $this->errcode = $json['errcode'];
       $this->errmsg = $json['errmsg'];
       return false;
      }
      return $json;
     }
     return false;
    }
    

    upload_meterial方法

    说明:该方法为调用微信上传永久素材接口方法

      /**
       * 请注意该方法必须保证php的版本在5.6以下,否则会爆40015错误
       */
      function upload_meterial($file_info,$access_token){
       $url="https://api.weixin.qq.com/cgi-bin/material/add_material?access_token={$access_token}&type=image";
       $ch1 = curl_init ();
       $timeout = 5;
       $real_path="{$file_info['filename']}";
       //$real_path=str_replace("/", "\", $real_path);
       $data= array("media"=>"@{$real_path}",'form-data'=>$file_info);
       curl_setopt ( $ch1, curlopt_url, $url );
       curl_setopt ( $ch1, curlopt_post, 1 );
       curl_setopt ( $ch1, curlopt_returntransfer, 1 );
       curl_setopt ( $ch1, curlopt_connecttimeout, $timeout );
       curl_setopt ( $ch1, curlopt_ssl_verifypeer, false );
       curl_setopt ( $ch1, curlopt_ssl_verifyhost, false );
       curl_setopt ( $ch1, curlopt_postfields, $data );
       $result = curl_exec ( $ch1 );
       echo '<br/>';
       echo 'reulst is ==========>'.$result;
       curl_close ( $ch1 );
       if(curl_errno()==0){
        $result=json_decode($result,true);
        //var_dump($result);
        return $result['media_id'];
       }else {
        return false;
       }
      }
    

    http_post方法

    说明:该方法为调http post请求方法

    /**
     * post 请求
     * @param string $url
     * @param array $param
     * @param boolean $post_file 是否文件上传
     * @return string content
     */
    private function http_post($url,$param,$post_file=false){
     $ocurl = curl_init();
     if(stripos($url,"https://")!==false){
      curl_setopt($ocurl, curlopt_ssl_verifypeer, false);
      curl_setopt($ocurl, curlopt_ssl_verifyhost, false);
      curl_setopt($ocurl, curlopt_sslversion, 1); //curl_sslversion_tlsv1
     }
     if (is_string($param) || $post_file) {
      $strpost = $param;
     } else {
      $apost = array();
      foreach($param as $key=>$val){
       $apost[] = $key."=".urlencode($val);
      }
      $strpost = join("&", $apost);
     }
     curl_setopt($ocurl, curlopt_url, $url);
     curl_setopt($ocurl, curlopt_returntransfer, 1 );
     curl_setopt($ocurl, curlopt_post,true);
     curl_setopt($ocurl, curlopt_postfields,$strpost);
     $scontent = curl_exec($ocurl);
     $astatus = curl_getinfo($ocurl);
     curl_close($ocurl);
     if(intval($astatus["http_code"])==200){
      return $scontent;
     }else{
      return false;
     }
    }
    

    遇到的问题

    在开发的过程中,在调用微信上传媒体文件时候始终得到的返回数据为

    {"errcode":41005,"errmsg":"media data missing hint: [3fst_0048e297]"}

    原因:php版本的问题,我本机的版本5.6,而带有@识别的php方法必须是5.5以下才能识别,5.5以上的版本将这个特性去除了。

    解决方法:更换php的版本到5.5或者5.5以下,不更换php的版本的方法暂时没有找到

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持硕编程。


    【说明】本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!

    相关教程推荐

    其他课程推荐