PHP实现微信JS-SDK接口选择相册及拍照并上传的方法


Posted in PHP onDecember 05, 2016

本文实例讲述了PHP实现微信JS-SDK接口选择相册及拍照并上传的方法。分享给大家供大家参考,具体如下:

理解:微信上传接口是拍照,或者选择本地照片,上传到微信的服务器,获取到一个id,通过token与这个id获取到图片,保存到服务器即可。

效果图:

PHP实现微信JS-SDK接口选择相册及拍照并上传的方法

通过微信js接口,调用底层程序。
需要引入js文件,并进行配置。

<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
wx.config({
  debug: false,
  appId: 'wxed7996e9ad58345d',
  timestamp: 1449717454,
  nonceStr: 'asdfasdfasdf',
  signature: 'b74fb4ab4790172d2ab7e58f0051a1523aaa4803',
  jsApiList: [
    'chooseImage',
    'uploadImage'
  ]
});

其中appId为微信公众平台id,timestamp为当前时间戳,nonceStr为随机字符串,signature为签名。

signature是最重要参数。需要通过很多步骤来获取。

首先获取access_token,能存活两小时,每天允许获取2000次。超过就不能获取了。

// 获取access_token 两小时有效
private function get_access_token(){
    $appid = C('oauth_config.appid');
    $appsecret = C('oauth_config.appsecret');
    $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$appid.'&secret='.$appsecret;
    $rurl = file_get_contents($url);
    $rurl = json_decode($rurl,true);
    if(array_key_exists('errcode',$rurl)){
      return false;
    }else{
      $access_token = $rurl['access_token'];
      return $access_token;
    }
}

然后获取jsticket

// 获取jsticket 两小时有效
private function getjsticket(){ // 只允许本类调用,继承的都不可以调用,公开调用就更不可以了
    $access_token = $this->get_access_token();
    $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=".$access_token."&type=jsapi"; // 两小时有效
    $rurl = file_get_contents($url);
    $rurl = json_decode($rurl,true);
    if($rurl['errcode'] != 0){
      return false;
    }else{
      $jsticket = $rurl['ticket'];
      return $jsticket;
    }
}

然后获取signature,它是由多个参数拼接加密形成的,有实效性。

// 获取 signature
private function getsignature(){
    $noncestr = '';
    $jsapi_ticket = $this->getjsticket();
    $timestamp = time();
    $url = 'http://zhudianbao.diandodo.com/index.php?g=Opener&m=Merchant&a=open';
    $string1 = 'jsapi_ticket='.$jsapi_ticket.'&noncestr='.$noncestr.'×tamp='.$timestamp.'&url='.$url;
    $signature = sha1($string1);
    return $signature;
}

配置好之后,就可以使用了。我用了两个功能,一个是选择照片,一个是上传照片。

function chooseImage(obj){
  // 选择张片
  wx.chooseImage({
    count: 1, // 默认9
    sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
    sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
    success: function(res) {
      var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
      $(obj).attr('src', localIds);
      // 上传照片
      wx.uploadImage({
        localId: '' + localIds,
        isShowProgressTips: 1,
        success: function(res) {
          serverId = res.serverId;
          $(obj).next().val(serverId); // 把上传成功后获取的值附上
        }
      });
    }
  });
}

选择照片返回的localIds很有意思,可以用于上传使用,并且可以放在img的src属性中,展示图片。

上传成功后,获取一个serverId,通过这个id可以下载上传到微信服务器上的图片文件,把它保存到自己的服务器中。

// 获取图片地址
private function getmedia($access_token,$media_id,$foldername){
    $url = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=".$access_token."&media_id=".$media_id;
    if (!file_exists("./Uploads/User_cert/".$foldername)) {
      mkdir("./Uploads/User_cert/".$foldername, 0777, true);
    }
    $targetName = './Uploads/User_cert/'.$foldername.'/'.date('YmdHis').rand(1000,9999).'.jpg';
    $ch = curl_init($url); // 初始化
    $fp = fopen($targetName, 'wb'); // 打开写入
    curl_setopt($ch, CURLOPT_FILE, $fp); // 设置输出文件的位置,值是一个资源类型
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_exec($ch);
    curl_close($ch);
    fclose($fp);
    return $targetName;
}

防止图片名称相同,加一个rand随机数,因为在同一秒钟可能会上传多张照片。

$targetName = './Uploads/User_cert/'.$foldername.'/'.date('YmdHis').rand(1000,9999).'.jpg';

这个serverId以表单的形式提交到服务器,然后对其进行写入文件,获取地址,并把地址保存到服务器中。

微信的js与jquery不冲突,可以共同使用。

附上牛逼的JSSDK类

<?php
class JSSDK {
 private $appId;
 private $appSecret;
 public function __construct($appId, $appSecret) {
  $this->appId = $appId;
  $this->appSecret = $appSecret;
 }
 public function getSignPackage() {
  $jsapiTicket = $this->getJsApiTicket();
  // 注意 URL 一定要动态获取,不能 hardcode.
  $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
  $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
  $timestamp = time();
  $nonceStr = $this->createNonceStr();
  // 这里参数的顺序要按照 key 值 ASCII 码升序排序
  $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url";
  $signature = sha1($string);
  $signPackage = array(
   "appId"   => $this->appId,
   "nonceStr" => $nonceStr,
   "timestamp" => $timestamp,
   "url"    => $url,
   "signature" => $signature,
   "rawString" => $string
  );
  return $signPackage; 
 }
 private function createNonceStr($length = 16) {
  $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  $str = "";
  for ($i = 0; $i < $length; $i++) {
   $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
  }
  return $str;
 }
 private function getJsApiTicket() {
  // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例
  $data = json_decode(file_get_contents("jsapi_ticket.json"));
  if ($data->expire_time < time()) {
   $accessToken = $this->getAccessToken();
   // 如果是企业号用以下 URL 获取 ticket
   // $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken";
   $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
   $res = json_decode($this->httpGet($url));
   $ticket = $res->ticket;
   if ($ticket) {
    $data->expire_time = time() + 7000;
    $data->jsapi_ticket = $ticket;
    $fp = fopen("jsapi_ticket.json", "w");
    fwrite($fp, json_encode($data));
    fclose($fp);
   }
  } else {
   $ticket = $data->jsapi_ticket;
  }
  return $ticket;
 }
 private function getAccessToken() {
  // access_token 应该全局存储与更新,以下代码以写入到文件中做示例
  $data = json_decode(file_get_contents("access_token.json"));
  if ($data->expire_time < time()) {
   // 如果是企业号用以下URL获取access_token
   // $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$this->appId&corpsecret=$this->appSecret";
   $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret";
   $res = json_decode($this->httpGet($url));
   $access_token = $res->access_token;
   if ($access_token) {
    $data->expire_time = time() + 7000;
    $data->access_token = $access_token;
    $fp = fopen("access_token.json", "w");
    fwrite($fp, json_encode($data));
    fclose($fp);
   }
  } else {
   $access_token = $data->access_token;
  }
  return $access_token;
 }
 private function httpGet($url) {
  $curl = curl_init();
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($curl, CURLOPT_TIMEOUT, 500);
  // 为保证第三方服务器与微信服务器之间数据传输的安全性,所有微信接口采用https方式调用,必须使用下面2行代码打开ssl安全校验。
  // 如果在部署过程中代码在此处验证失败,请到 http://curl.haxx.se/ca/cacert.pem 下载新的证书判别文件。
  curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
  curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);
  curl_setopt($curl, CURLOPT_URL, $url);
  $res = curl_exec($curl);
  curl_close($curl);
  return $res;
 }
}

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
一个目录遍历函数
Oct 09 PHP
用PHP 4.2书写安全的脚本
Oct 09 PHP
PHP提取中文首字母
Apr 09 PHP
Ajax+PHP 边学边练 之二 实例
Nov 24 PHP
Discuz Uchome ajaxpost小技巧
Jan 04 PHP
PHP中几个常用的魔术常量
Feb 23 PHP
PHP filter_var() 函数 Filter 函数
Apr 25 PHP
PHP 简易输出CSV表格文件的方法详解
Jun 20 PHP
thinkphp路由规则使用示例详解和伪静态功能实现(apache重写)
Feb 24 PHP
php导入模块文件分享
Mar 17 PHP
yii2中使用Active Record模式的方法
Jan 09 PHP
在laravel框架中实现封装公共方法全局调用
Oct 14 PHP
thinkPHP js文件中U方法不被解析问题的解决方法
Dec 05 #PHP
thinkPHP中验证码的简单实现方法
Dec 05 #PHP
php获取当前月与上个月月初及月末时间戳的方法
Dec 05 #PHP
简述php环境搭建与配置
Dec 05 #PHP
php 变量引用与变量销毁机制详细介绍
Dec 05 #PHP
[原创]php实现 data url的图片生成与保存
Dec 04 #PHP
php 魔术常量详解及实例代码
Dec 04 #PHP
You might like
PHP如何得到当前页和上一页的地址?
2006/11/27 PHP
php中curl使用指南
2015/02/05 PHP
php数字每三位加逗号的功能函数
2015/10/22 PHP
基于PHP如何把汉字转化为拼音
2015/12/11 PHP
WordPress中Gravatar头像缓存到本地及相关优化的技巧
2015/12/19 PHP
jQuery学习3:操作元素属性和特性
2010/02/07 Javascript
JS获取页面窗口大小的代码解读
2011/12/01 Javascript
浅谈javascript中的作用域
2012/04/07 Javascript
jQuery CSS()方法改变现有的CSS样式
2014/08/20 Javascript
值得分享的bootstrap table实例
2016/09/22 Javascript
jQuery ui autocomplete选择列表被Bootstrap模态窗遮挡的完美解决方法
2016/09/23 Javascript
JavaScript事件方法(实例讲解)
2017/06/27 Javascript
Angular2生命周期钩子函数的详细介绍
2017/07/10 Javascript
JS秒杀倒计时功能完整实例【使用jQuery3.1.1】
2019/09/03 jQuery
vue实现抖音时间转盘
2019/09/08 Javascript
vue 验证码界面实现点击后标灰并设置div按钮不可点击状态
2019/10/28 Javascript
element-ui点击查看大图的方法示例
2020/12/14 Javascript
python绘制直线的方法
2018/06/30 Python
python GUI库图形界面开发之PyQt5拖放控件实例详解
2020/02/25 Python
Python itertools.product方法代码实例
2020/03/27 Python
意大利团购网站:Groupon意大利
2016/10/11 全球购物
MADE法国:提供原创设计师家具
2018/09/18 全球购物
Parfumdreams芬兰:购买香水和化妆品
2021/02/13 全球购物
简述进程的启动、终止的方式以及如何进行进程的查看
2014/02/20 面试题
计算机求职信
2013/12/01 职场文书
各营销点岗位职责范本
2014/03/05 职场文书
婚礼主持结束词
2014/03/13 职场文书
单位委托书范本
2014/04/04 职场文书
计算机专业求职信
2014/06/02 职场文书
计算机毕业生自荐信
2014/06/12 职场文书
运动会横幅标语
2014/06/17 职场文书
爱的奉献演讲稿
2014/09/10 职场文书
2014公司年终工作总结
2014/12/19 职场文书
2015年平安创建工作总结
2015/04/29 职场文书
2015年信息中心工作总结
2015/05/25 职场文书
七一表彰大会简报
2015/07/20 职场文书