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


Posted in PHP onApril 11, 2017

功能需求

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

开发说明

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

使用到的接口

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

环境要求

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的版本的方法暂时没有找到

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
第五节 克隆 [5]
Oct 09 PHP
测试您的 PHP 水平的题目
May 30 PHP
php+AJAX传送中文会导致乱码的问题的解决方法
Sep 08 PHP
ajax实现无刷新分页(php)
Jul 18 PHP
如何在php中正确的使用json
Aug 06 PHP
PHP APC缓存配置、使用详解
Mar 06 PHP
标准PHP的AES加密算法类
Mar 12 PHP
php校验表单检测字段是否为空的方法
Mar 20 PHP
分享ThinkPHP3.2中关联查询解决思路
Sep 20 PHP
详解php设置session(过期、失效、有效期)
Nov 12 PHP
mac系统下安装多个php并自由切换的方法详解
Apr 21 PHP
PHP示例演示发送邮件给某个邮箱
Apr 03 PHP
php array_reverse 以相反的顺序返回数组实例代码
Apr 11 #PHP
PHP和MYSQL实现分页导航思路详解
Apr 11 #PHP
php 一维数组的循环遍历实现代码
Apr 10 #PHP
删除PHP数组中的重复元素的实现代码
Apr 10 #PHP
删除PHP数组中头部、尾部、任意元素的实现代码
Apr 10 #PHP
PHP数组中头部和尾部添加元素的方法(array_unshift,array_push)
Apr 10 #PHP
yii2使用gridView实现下拉列表筛选数据
Apr 10 #PHP
You might like
浏览器关闭后,能继续执行的php函数(ignore_user_abort)
2012/08/01 PHP
体育彩票排列三组选三算法分享
2014/03/07 PHP
PHP编程文件处理类SplFileObject和SplFileInfo用法实例分析
2017/07/22 PHP
JQuery操作Select的Options的Bug(IE8兼容性视图模式)
2013/04/21 Javascript
ExtJS4中的requires使用方法示例介绍
2013/12/03 Javascript
前端微信支付js代码
2016/07/25 Javascript
JS两种类型的表单提交方法实例分析
2016/11/28 Javascript
js将字符串中的每一个单词的首字母变为大写其余均为小写
2017/01/05 Javascript
jquery点赞功能实现代码 点个赞吧!
2020/05/29 jQuery
浅谈vuejs实现数据驱动视图原理
2018/02/23 Javascript
小程序实现人脸识别功能(百度ai)
2018/12/23 Javascript
详解mpvue中小程序自定义导航组件开发指南
2019/02/11 Javascript
详解JavaScript 为什么要有 Symbol 类型?
2019/04/03 Javascript
Python中生成器和yield语句的用法详解
2015/04/17 Python
全面解析Python的While循环语句的使用方法
2015/10/13 Python
Python两个内置函数 locals 和globals(学习笔记)
2016/08/28 Python
python实现年会抽奖程序
2019/01/22 Python
浅谈python中get pass用法
2019/03/19 Python
Django高级编程之自定义Field实现多语言
2019/07/02 Python
python模块常用用法实例详解
2019/10/17 Python
python实现淘宝购物系统
2019/10/25 Python
CentOS7下安装python3.6.8的教程详解
2020/01/03 Python
Keras 实现加载预训练模型并冻结网络的层
2020/06/15 Python
canvas实现二维码和图片合成的示例代码
2018/08/01 HTML / CSS
美国女性服饰销售网站:Nasty Gal(坏女孩)
2016/07/26 全球购物
玩具反斗城天猫官方旗舰店:享誉全球的玩具店
2017/10/10 全球购物
联想香港官方网站及网店:Lenovo香港
2018/04/13 全球购物
屈臣氏俄罗斯在线商店:Watsons俄罗斯
2020/08/03 全球购物
父亲生日宴会答谢词
2014/01/10 职场文书
最新奶茶店创业计划书
2014/01/25 职场文书
环保建议书500字
2014/05/14 职场文书
违纪检讨书范文
2015/01/27 职场文书
市场部岗位职责
2015/02/12 职场文书
行政人事专员岗位职责
2015/04/07 职场文书
JS数组的常用方法整理
2021/03/31 Javascript
在CSS中使用when/else的方法
2022/01/18 HTML / CSS