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 相关文章推荐
用PHP来写记数器(详细介绍)
Oct 09 PHP
网友原创的PHP模板类代码
Sep 07 PHP
php 时间计算问题小结
Jan 04 PHP
frename PHP 灵活文件命名函数 frename
Sep 09 PHP
Mysql的Root密码忘记,查看或修改的解决方法(图文介绍)
Jun 14 PHP
ThinkPHP自动填充实现无限级分类的方法
Aug 22 PHP
PHP面向对象精要总结
Nov 07 PHP
浅谈PHP中Stream(流)
Jun 08 PHP
tp5框架使用composer实现日志记录功能示例
Jan 10 PHP
php ActiveMQ的安装与使用方法图文教程
Feb 23 PHP
PhpStorm2020 + phpstudyV8 +XDebug的教程详解
Sep 17 PHP
宝塔面板出现“open_basedir restriction in effect. ”的解决方法
Mar 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/10/09 PHP
投票管理程序
2006/10/09 PHP
逐步提升php框架的性能
2008/01/10 PHP
PHP+MySQL统计该库中每个表的记录数并按递减顺序排列的方法
2016/02/15 PHP
如何将JS的变量值传递给ASP变量
2012/12/10 Javascript
自己写的兼容ie和ff的在线文本编辑器类似ewebeditor
2012/12/12 Javascript
jquery移动点击的项目到列表最顶端的方法
2015/06/24 Javascript
javascript顺序加载图片的方法
2015/07/18 Javascript
WordPress中鼠标悬停显示和隐藏评论及引用按钮的实现
2016/01/12 Javascript
JS简单实现String转Date的方法
2016/03/02 Javascript
JavaScript兼容性总结之获取非行间样式案例
2016/08/07 Javascript
jQuery如何跳转到另一个网页 就这么简单
2016/12/28 Javascript
angular实现商品筛选功能
2017/02/01 Javascript
正则验证小数点后面只能有两位数的方法
2017/02/28 Javascript
80%应聘者都不及格的JS面试题
2017/03/21 Javascript
Vue 组件间的样式冲突污染
2017/08/31 Javascript
bootstrap fileinput插件实现预览上传照片功能
2018/01/23 Javascript
详解如何使用node.js的开发框架express创建一个web应用
2018/12/20 Javascript
基于vue实现圆形菜单栏组件
2019/07/05 Javascript
vue-model实现简易计算器
2020/08/17 Javascript
[01:15:00]LGD vs Mineski Supermajor 胜者组 BO3 第一场 6.5
2018/06/06 DOTA
详解Python的Twisted框架中reactor事件管理器的用法
2016/05/25 Python
python回调函数中使用多线程的方法
2017/12/25 Python
python文字转语音实现过程解析
2019/11/12 Python
opencv3/C++图像像素操作详解
2019/12/10 Python
使用tensorflow实现矩阵分解方式
2020/02/07 Python
解决keras模型保存h5文件提示无此目录问题
2020/07/01 Python
python打开音乐文件的实例方法
2020/07/21 Python
纯css3实现的动画按钮的实例教程
2014/11/17 HTML / CSS
土耳其时尚购物网站:Morhipo
2017/09/04 全球购物
澳大利亚最大的女装零售商:Millers
2017/09/10 全球购物
秘书岗位职责
2013/11/18 职场文书
出国留学担保书
2014/05/20 职场文书
关于对大人不礼貌的检讨书
2014/09/29 职场文书
婚前保证书范文
2015/02/28 职场文书
python利用pandas分析学生期末成绩实例代码
2021/07/09 Python