在微信服务号中开发上传图片功能php
后端 php yii2 前端javscript前端
1.https 域 下前端处理base64为图片,苹果不支持。
2.七牛的fech接口很坑,有些数据不能存储,随机性的成功。ajax
1.经过微信的接口,调取手机的拍照和选取相册很方即可以设置选择几张和原图和缩略图,而后上传到微信的服务>器,返回一个media_id发送到后端,经过微信的文件媒体接口获取数据(数据token只存在两个小时),而后经过php
处理成base64位数据,上传到七牛,七牛返回连接存储在本地。
2.前端处理图片到七牛返回发到后端json
<div class="page-group"> <div class="page"> <div class="content" style="background-color: white;"> <img src="/image/distant/distant-view.png" width="100%"> <div class="distant-click"> <?php if ($model->distant_view) { echo '<img id="distant-click-img" src="'.$model->distant_view.'" width="100%" alt="" />'; }else { echo '<img id="distant-click-img" src="/image/distant/distant-click.png" width="100%" alt="" />'; } ?> </div> <input type="hidden" id='token' value ="<?php echo $token;?>" name=""> <div class="wish-hider-next-button"> <span id="submit">下一步</span> </div> </div> </div> </div> <script> <?php $wechat = Yii::$app->wechat; ?> wx.config(<?php echo json_encode( $wechat->jsApiConfig( [ "jsApiList" => [ "onMenuShareTimeline", "onMenuShareAppMessage", "onMenuShareQQ", "onMenuShareWeibo", "chooseImage", 'uploadImage' ] ] ) ); ?>) Zepto(function($){ var obj = $('#distant-click-img'); var id = "<?=$id?>"; var _csrf = "<?= Yii::$app->request->getCsrfToken()?>"; var distant_src = $("#distant-click-img").attr('src'); var flag = 0; if(distant_src != '/image/distant/distant-click.png'){ flag = 1; } wx.ready(function() { 微信上传代码 // 点击更换按钮 $('#distant-click-img').click(function(){ wx.chooseImage({ count: 1, // 默认9 选择几张照片 sizeType: ['compressed'], // 能够指定是原图仍是压缩图,默认两者都有 sourceType: ['album', 'camera'], // 能够指定来源是相册仍是相机,默认两者都有 success: function (res) { var localIds = res.localIds; // 返回选定照片的本地ID列表,localId能够做为img标签的src属性显示图片 obj.attr('src',localIds) flag = 0; UpToWexinService(); } }); // 上传图片到微信服务器 function UpToWexinService() { var src = obj.attr('src'); wx.uploadImage({ localId: src, // 须要上传的图片的本地ID,由chooseImage接口得到 isShowProgressTips: 1, // 默认为1,显示进度提示 success: function (res) { // 把图片保存在本身的服务器 saveImageInfo(res.serverId); } }); } }) /** * 上传远景图片到本身的服务器 * @param [type] imgData [description] * @return [type] [description] */ function saveImageInfo(imgData) { $.ajax({ url:'save-distant-img-data', type:'post', data:{'id':id,'img':imgData,'_csrf':_csrf}, success:function(res){ if (res.data.status == 1) { flag = 1 $.toast(res.data.data); } else { $.toast(res.data.data); } }, error:function(res){ $.toast("图片上传错误"); } }) } }) }) </script>
注意 网站使用了https,苹果手机不能处理。后端
/** * 上传64位编码到七牛 * @param [type] data [description] * @return [type] [description] */ function putb64(data){ var pic = data; var token = $('#token').val(); var url = "https://upload.qiniu.com/putb64/-1"; var xhr = new XMLHttpRequest(); xhr.onreadystatechange=function(){ if (xhr.readyState==4){ var str =JSON.parse(xhr.responseText) var srcImg = 'https://obf949end.qnssl.com/'+str.key; $('#distant-click-img').attr('src',srcImg); saveImageInfo(srcImg); } } xhr.open("POST", url, true); xhr.setRequestHeader("Content-Type", "application/octet-stream"); xhr.setRequestHeader("Authorization", "UpToken "+token); xhr.send(pic); }
七牛有点坑,说明很不明确,处理个图片到七牛,找到两个接口,fetch 和 pubtb64api
fetch 不稳定老是失败,不知道是否是跨域或者拦截,感受不可靠。最终又改为了pubtb64位处理的跨域
本身在开发的过程当中,各类百度,谷歌,不多有给全的代码,都靠本身去猜。在这里贴上所有代码,节省你们时间。服务器
注释尽可能加全,把全部的都集中在这里 /** * 把图片存在服务器上面 * @return [type] [description] */ public function actionSaveDistantImgData() { Yii::$app->response->format = Response::FORMAT_JSON; $request = Yii::$app->request; $data = $request->post(); $img = $data['img']; $id = $data['id']; // 获取七牛的token $token = self::GetUploadToken(); $upToken = $token['token']; // 获取微信的 access_token $weixin_token = \DockerEnv::get('WEIXIN_TOKEN'); $appid = \DockerEnv::get('WEIXIN_APP_ID'); $secret = \DockerEnv::get('WEIXIN_APP_SECRET'); $url_get = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$secret; $json=$this->curlGet($url_get); $weixin_token = json_decode($json); $weixin_token=$weixin_token->access_token; // 从微信服务器下载 $str = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=".$weixin_token."&media_id=".$img; // 把从微信得到的数据用七牛上传到服务器上面 $access_key = \DockerEnv::get('QINIU_ACCESS_KEY'); $secret_key = \DockerEnv::get('QINIU_SECRET_KEY'); $this->request_by_curl($remote_server,$post_string,$upToken); $strr = file_get_contents($str); $fetch =base64_encode($strr); $imggg = $this->request_by_curl('http://upload.qiniu.com/putb64/-1',$fetch,$upToken); $imgs = json_decode(trim($imggg),true); $imgss = $imgs['hash']; $imgUrl = 'https://obf949end.qnssl.com/'.$imgss.'?imageslim'; // 把远景数据存在试管表里面 $test_tube = TestTube::findOne($id); $test_tube->distant_view = $imgUrl; $test_tube->save(); // 把远景图片存在藏匿者表里 $solid_sneak = SolidSneak::find()->where(['test_tube_id' => $id])->one(); $solid_sneak->distant_view = $imgUrl; $solid_sneak->updated_at = time(); if ($solid_sneak->save()) { return ['status' => 1,'data' => '图片上传成功']; } return ['status' => 0,'data' => '图片上传失败']; }
public function curlGet($url){ $ch = curl_init(); $header = "Accept-Charset: utf-8"; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // curl_setopt($curl, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)'); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_AUTOREFERER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $temp = curl_exec($ch); return $temp; } public function send($url, $header = '') { $curl = curl_init($url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_HEADER,0); curl_setopt($curl, CURLOPT_HTTPHEADER, $header); curl_setopt($curl, CURLOPT_POST, 1); $con = curl_exec($curl); if ($con === false) { echo 'CURL ERROR: ' . curl_error($curl); } else { return $con; } } public function urlsafe_base64_encode($str){ $find = array("+","/"); $replace = array("-", "_"); return str_replace($find, $replace, base64_encode($str)); } public function request_by_curl($remote_server,$post_string,$upToken) { $headers = array(); $headers[] = 'Content-Type:image/png'; $headers[] = 'Authorization:UpToken '.$upToken; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,$remote_server); //curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_HTTPHEADER ,$headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($ch, CURLOPT_TIMEOUT, 30); $data = curl_exec($ch); curl_close($ch); return $data; } /** * generate_access_token * * @desc 签名运算 * @param string $access_key * @param string $secret_key * @param string $url * @param array $params * @return string */ public function generate_access_token($access_key, $secret_key, $url, $params = ''){ $parsed_url = parse_url($url); $path = $parsed_url['path']; $access = $path; if (isset($parsed_url['query'])) { $access .= "?" . $parsed_url['query']; } $access .= "\n"; if($params){ if (is_array($params)){ $params = http_build_query($params); } $access .= $params; } $digest = hash_hmac('sha1', $access, $secret_key, true); return $access_key.':'.$this->urlsafe_base64_encode($digest); } public function base64EncodeImage ($image_file) { $base64_image = ''; $image_info = getimagesize($image_file); $image_data = fread(fopen($image_file, 'r'), filesize($image_file)); $base64_image = 'data:' . $image_info['mime'] . ';base64,' . chunk_split(base64_encode($image_data)); return $base64_image; }