功能需求

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

开发说明

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

使用到的接口

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

环境要求

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

开发流程

1、从公司平台获取所有的文章列表2、遍历文章列表,查看文章是否有图片附件,若有进行第三步,否则进行第四步3、检测所有的附件,取出第一个图片附件,并调用新增媒体文件接口上传图片获得返回后的media_id4、调用素材列表接口获取默认的封面图片,并从中得到的数据中获取media_id5、根据返回获取到的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的版本的方法暂时没有找到

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