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 相关文章推荐
967 个函式
Oct 09 PHP
BBS(php &amp; mysql)完整版(五)
Oct 09 PHP
php学习之数据类型之间的转换代码
May 29 PHP
php学习之function的用法
Jul 14 PHP
php+ajax实现的点击浏览量加1
Apr 16 PHP
百度工程师讲PHP函数的实现原理及性能分析(一)
May 13 PHP
PHP新建类问题分析及解决思路
Nov 19 PHP
完美解决Thinkphp3.2中插入相同数据的问题
Aug 01 PHP
PHP实现防止表单重复提交功能【基于token验证】
May 24 PHP
Ubuntu中支持PHP5与PHP7双版本的简单实现
Aug 19 PHP
PHP如何搭建百度Ueditor富文本编辑器
Sep 21 PHP
laravel框架使用阿里云短信发送消息操作示例
Feb 15 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中获取指定IP的物理地址的代码(正则表达式)
2011/06/23 PHP
php调整gif动画图片尺寸示例代码分享
2013/12/05 PHP
PHP 绘制网站登录首页图片验证码
2016/04/12 PHP
PHP后台备份MySQL数据库的源码实例
2019/03/18 PHP
符合W3C网页标准的iframe标签的使用方法
2007/07/19 Javascript
JS Array对象入门分析
2008/10/30 Javascript
js下用gb2312编码解码实现方法
2009/12/31 Javascript
跨浏览器开发经验总结(三)   警惕“IE依赖综合症”
2010/05/13 Javascript
js表头排序实现方法
2015/01/16 Javascript
Javascript中实现String.startsWith和endsWith方法
2015/06/10 Javascript
JS写谷歌浏览器chrome的外挂实例
2018/01/11 Javascript
vue表单自定义校验规则介绍
2018/08/28 Javascript
[51:06]DOTA2-DPC中国联赛 正赛 Elephant vs Aster BO3 第二场 1月26日
2021/03/11 DOTA
Python使用scrapy采集数据时为每个请求随机分配user-agent的方法
2015/04/08 Python
Python下载懒人图库JavaScript特效
2015/05/28 Python
深入学习python多线程与GIL
2019/08/26 Python
wxPython实现分隔窗口
2019/11/19 Python
Python基础之函数原理与应用实例详解
2020/01/03 Python
Python如何基于rsa模块实现非对称加密与解密
2020/01/03 Python
Pycharm中import torch报错的快速解决方法
2020/03/05 Python
Anaconda+VSCode配置tensorflow开发环境的教程详解
2020/03/30 Python
美国50岁以上单身人士约会平台:SilverSingles
2018/06/29 全球购物
法国二手手袋、手表和奢侈珠宝购物网站:Collector Square
2018/07/05 全球购物
英国在线药房:Chemist.co.uk
2019/03/26 全球购物
澳大利亚礼品卡商店:Gift Card Store
2019/06/24 全球购物
机械制造专业毕业生求职信
2014/03/02 职场文书
战略合作意向书范本
2014/04/01 职场文书
主持人演讲稿
2014/05/13 职场文书
信访维稳工作汇报
2014/10/27 职场文书
优秀班组事迹材料
2014/12/24 职场文书
审美与表现自我评价
2015/03/09 职场文书
共青团员自我评价
2015/03/10 职场文书
工程款催款函
2015/06/24 职场文书
法律服务所工作总结
2015/08/10 职场文书
婚礼必备主持词范本!
2019/07/23 职场文书
研究生学习计划书应该怎么写?
2019/09/10 职场文书