说,我有一个需求,就是一个临时功能。由于工作开发问题,我们有一个B项目,需要有一个商品添加的功能,涉及到添加商品内容,比如商品名字,商品描述,商品库存,商品图片等。后台商品添加的接口已经写完了,但是问题是目前没有后台页面,就是产品还没有出后台详细页面。前端已经完备了,上线了。后台还需要工作时间处理。所以目前的处理方法是在我们已经存在的A项目后台中,添加一个对B项目添加商品的功能。

  

  一、当下问题

  1、在我们已有的A项目中,新增一个添加商品的功能,这个本来是没有什么问题的,因为目前A项目中本身就已经连接了B项目的数据库,所以商品属性的新增和修改都没什么问题。主要是商品图片的上传这里,有点问题。B项目已经对外提供了上传图片的接口,但是由于我确实对前端不是特别熟悉。所以在A项目中的后台JS中调取B项目的上传图片的接口时,一直提示"CORS",这里应该是存在一个跨域的问题,虽然我PHP接口端已经对跨域做了处理(入口文件处),但是貌似JS这边也需要相应的调整。

// [ 应用入口文件 ]
//入口文件index.php
namespace think; // 加载基础文件
require __DIR__ . '/thinkphp/base.php'; // 支持事先使用静态方法设置Request对象和Config对象
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Content-Type,XFILENAME,XFILECATEGORY,XFILESIZE,authorization");
// 执行应用并响应
Container::get('app')->bind('api')->run()->send();

  2、无奈小白JS功底不够扎实,所以我这边准备通过A项目中调取后台PHP接口,然后通过在PHP代码中接受web端参数,然后再转发,调取B项目中上传图片的接口,试图完成功能。于是先通过Postman接口工具测试了一下B项目上传图片的接口是否有效。如图3,发现确实没有什么问题,于是就准备如此处理。

  3、但是实际是,在调取时,我们常用的传参数方式是GET或者POST方式,但是我们知道文件上传是通过$_FILES接受,下面是B项目的上传图片的控制器代码(用的是TP5.1),接受是通过内置的file方式。

    /**上传图片
* @param Request $request
*/
public function uploadImg(Request $request){
$file = $request->file('image');
$type = $request->post('type', 0);
// 移动到框架应用根目录/uploads/ 目录下
$upload_path = config('common.upload_path');
switch ($type) {
case 1://门店
$path = $upload_path['shop_img'];
break;
case 2://投票活动
$path = $upload_path['vote_img'];
break;
case 3://投票活动参赛图片
$path = $upload_path['vote_contestant_img'];
break;
case 4://会员店铺logo图片
$path = $upload_path['member_shop'];
break;
case 5://自营商品图片
$path = $upload_path['self_goods'];
break;
default:
$path = $upload_path['common'];
break;
}
$save_path = env('root_path').$path;
$info = $file->validate(['ext'=>'jpg,jpeg,png,gif'])->move($save_path);
if($info){
$return = [
'extension' => $info->getExtension(),
'image_path' => $path.$info->getSaveName(),
'image_name' => $info->getFilename(),
];
$this->apiResult(CustomError::OPERATION_SUCCSESS, $return);
}else{
$this->apiResult(CustomError::OPERATION_FAILED, [], $file->getError());
}
}

  4、所以在转发A项目web端传来的,文件内容,就有点不知所措了。该死,该死。

//文件上传接受参数
array(1) {
["file_upload"] => array(5) {
["name"] => string(8) "timg.jpg"
["type"] => string(10) "image/jpeg"
["tmp_name"] => string(22) "C:\Windows\php73CE.tmp"
["error"] => int(0)
["size"] => int(355565)
}
}

  5、所以按刚才设想的,简单做下转发还是不行,这里面参数的传输方式应该还有另外一种,就是文件的类型。鉴于是通过Postman方式上传成功,这个工具确实很推荐多多学习,他不仅作为一个第三方中间为我们验证接口是否可用,更给我们提供了调取接口的各种代码Damo,如图3中标识的Code处,就是获取Damo的按钮。我们点击可以看见Postman给我提供了三种,调取接口的方式。

<?php
//1、HttpRequest 发送http请求
$request = new HttpRequest();
$request->setUrl('http://jszapi.dev.jingjinglego.com/index.php/index/uploadImg');
$request->setMethod(HTTP_METH_POST); $request->setHeaders(array(
'cache-control' => 'no-cache',
'Connection' => 'keep-alive',
'Content-Length' => '39091',
'Content-Type' => 'multipart/form-data; boundary=--------------------------296608706222243058746908',
'Accept-Encoding' => 'gzip, deflate',
'Host' => 'jszapi.dev.jingjinglego.com',
'Postman-Token' => 'dc010150-b166-4dec-a33f-959a65c91c71,be7315cb-ae21-404f-89fa-dddf5973eb3a',
'Cache-Control' => 'no-cache',
'Accept' => '*/*',
'User-Agent' => 'PostmanRuntime/7.15.2',
'content-type' => 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
)); $request->setBody('------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="image"; filename="785da43beca5a474.jpg"
Content-Type: image/jpeg ------WebKitFormBoundary7MA4YWxkTrZu0gW--'); try {
$response = $request->send(); echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
<?php
//2、pecl_http 需要开启PECL HTTP 扩展
$client = new http\Client;
$request = new http\Client\Request; $body = new http\Message\Body;
$body->addForm(NULL, array(
array(
'name' => 'image',
'type' => null,
'file' => '/E:/MyBooks/网站图标/网站素材/785da43beca5a474.jpg',
'data' => null
)
)); $request->setRequestUrl('http://jszapi.dev.jingjinglego.com/index.php/index/uploadImg');
$request->setRequestMethod('POST');
$request->setBody($body); $request->setHeaders(array(
'cache-control' => 'no-cache',
'Connection' => 'keep-alive',
'Content-Length' => '39091',
'Content-Type' => 'multipart/form-data; boundary=--------------------------296608706222243058746908',
'Accept-Encoding' => 'gzip, deflate',
'Host' => 'jszapi.dev.jingjinglego.com',
'Postman-Token' => 'dc010150-b166-4dec-a33f-959a65c91c71,3216cc22-be61-4d4b-8d41-c5178848b54f',
'Cache-Control' => 'no-cache',
'Accept' => '*/*',
'User-Agent' => 'PostmanRuntime/7.15.2'
)); $client->enqueue($request)->send();
$response = $client->getResponse(); echo $response->getBody();
<?php
//3、cURL 是一个非常强大的开源库,支持很多协议,包括HTTP、FTP、TELNET等,我们使用它来发送HTTP请求。
//它给我们带来的好处是可以通过灵活的选项设置不同的HTTP协议参数,并且支持HTTPS。CURL可以根据URL前缀是“HTTP” 还是“HTTPS”自动选择是否加密发送内容。 $curl = curl_init(); curl_setopt_array($curl, array(
CURLOPT_URL => "http://jszapi.dev.jingjinglego.com/index.php/index/uploadImg",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"image\"; filename=\"785da43beca5a474.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--",
CURLOPT_HTTPHEADER => array(
"Accept: */*",
"Accept-Encoding: gzip, deflate",
"Cache-Control: no-cache",
"Connection: keep-alive",
"Content-Length: 39091",
"Content-Type: multipart/form-data; boundary=--------------------------296608706222243058746908",
"Host: jszapi.dev.jingjinglego.com",
"Postman-Token: dc010150-b166-4dec-a33f-959a65c91c71,982e059e-bd8b-4db9-83c4-3fd52c8ed82f",
"User-Agent: PostmanRuntime/7.15.2",
"cache-control: no-cache",
"content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"
),
)); $response = curl_exec($curl);
$err = curl_error($curl); curl_close($curl); if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}

  6、如上面3个代码片段,但是后来验证后,发现1/3的参数,不知道是怎么传输的,2的参数很容易看懂,但是运用的话需要开启扩展,这个目前不太合适,所以┭┮﹏┭┮。

二、写在心里

  1、这个上传的问题,确实卡住了,感觉有点难过。其实每次都会遇见一个自己的困难,经常遇见,周末下午的时候,我在家打开电脑,打来远程,准备登陆下ftp拉下代码,发现一直连不上,心里那个烦啊。但是还是通过远程工具(向日葵),将代码拉下来了。想这个图片上传到底怎么弄了,之前也看过,关于通过ftp的方式上传图片,但是后来查看了相关文章需要在php.ini中开启,所以也作罢。

#开启ftp扩展支持
extension=php_ftp.dll

  2、经常遇见困难,经常觉得自己很LOW但是,已经工作了这么久,发现其实问题最后又都解决了,但是现在回想,却忘了到底是怎么解决的,所以写这个博文主要也是想记录下。一直到下午4点多,深圳的天气今年闷热居多,中午我已经昧着良心午休了1个小时,所以现在到现在心里还有些许内疚,唉。

  3、但是还是找不到解决的方法,头疼的厉害,好热。怎么办,我决定靠在椅子上休息下,于是我还是决定躺在沙发上睡会。刚躺下,想着这怎么办呢。

  -----------------------base64---------------------------华丽的分割线

  我突然想到了base64这个读起来,朗朗上口的函数,对如果现将图片转换成base64字符串,再通过POST方式传送给B项目,然后再B项目中对字符串进行解码,生成图片,保存到B项目,然后返回图片路径,不就可以了吗。于是我有推了一遍,发现没有疏忽。于是觉得应该是解决了。

三、解决图片上传问题

  1、A接受web传来图片临时文件,

    #上传图片京手指 1:图片保留到本地
public function uploadJszImg()
{$path = config('business.jsz_file_tem');
$file = request()->file('file_upload');
$info = $file->validate(['ext'=>'jpg,jpeg,png,gif'])->move($path);//图片保存到本地
$img_one = $path.$info->getSaveName();//图片路径
$img_base = imgToBase64($img_one);//获取图片base64编码格式
deleteFileWay($path);//删除临时文件
$url = config('business.jsz_api')['baseImg'];
$data = [
'base_string'=> $img_base,
'path' => 'upload/goods_img',
];
$res = http_api($url,$data,1);
$res = json_decode($res,true);
if($res['data']){
$return = ['code'=>1,'message'=>'成功','data'=>'jszapi.dev.jingjinglego.com'.$res['data']];
}else{
$return = ['code'=>0,'message'=>'失败'];
}
return $return;
}

  2、并转换成base64字符串,

/**
* 获取图片的Base64编码(不支持url)
* @param $img_file 传入本地图片地址
* @return string
*/
function imgToBase64($img_file) {
$img_base64 = '';
if (file_exists($img_file)) {
$app_img_file = $img_file; // 图片路径
$img_info = getimagesize($app_img_file); // 取得图片的大小,类型等
//echo '<pre>' . print_r($img_info, true) . '</pre><br>';
$fp = fopen($app_img_file, "r"); // 图片是否可读权限
if ($fp) {
$filesize = filesize($app_img_file);
$content = fread($fp, $filesize);
$file_content = chunk_split(base64_encode($content)); // base64编码
switch ($img_info[2]) { //判读图片类型
case 1: $img_type = "gif";
break;
case 2: $img_type = "jpg";
break;
case 3: $img_type = "png";
break;
}
$img_base64 = 'data:image/' . $img_type . ';base64,' . $file_content;//合成图片的base64编码
}
fclose($fp);
}
return $img_base64; //返回图片的base64
}

  3、B接受A项目传来参数

    /**
* 将base64字符串转换成图片并保存在本地
* @param Request $request
* @return void
*/
public function baseImg(Request $request)
{
$base_string = $request->post('base_string', '');
if (!$base_string) {
$this->apiResult(CustomError::MISSING_PARAMS);
}
$path = $request->post('path', '');
if (!$path) {
$this->apiResult(CustomError::MISSING_PARAMS);
}
$request = base64_image_content($base_string, $path);//解码
if($request){
$this->apiResult(CustomError::OPERATION_SUCCSESS, $request);
}else{
$this->apiResult(CustomError::OPERATION_FAILED);
}
}

  4、对字符解析解码

/**
* [将Base64图片转换为本地图片并保存]
* @param [Base64] $base64_image_content [要保存的Base64]
* @param [目录] $path [要保存的路径]
*/
function base64_image_content($base64_image_content,$path){
//匹配出图片的格式
if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)){
$type = $result[2];
$new_file = $path."/".date('Ymd',time())."/";
if(!file_exists($new_file)){
//检查是否有该文件夹,如果没有就创建,并给予最高权限
mkdir($new_file, 0700);
}
$new_file = $new_file.time().".{$type}";
if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_image_content)))){
return '/'.$new_file;
}else{
return false;
}
}else{
return false;
}
}

  5、最后返回上传好的图片路径

:结束

PHP代码篇(五)--如何将图片文件上传到另外一台服务上的更多相关文章

  1. PHP文件上传至另一台服务器

    PHP程序上传文件时,想指定上传到另一台服务器. move_uploaded_file这个方法第二个参数指定的存放路径需要和php程序文件一个服务器,没办法指定其他服务器的地址,本人才疏学浅,哪位大哥 ...

  2. ASP.NET工作笔记之一:图片上传预览及无刷新上传

    转自:http://www.cnblogs.com/sibiyellow/archive/2012/04/27/jqueryformjs.html 最近项目里面涉及到无刷新上传图片的功能,其实也就是上 ...

  3. 怎么样通过php使用html5实现多文件上传?(php多图上传)

    <!DOCTYPE html><html lang="zh-cn"> <head> <meta charset="utf-8&q ...

  4. Thinkphp5图片上传正常,音频和视频上传失败的原因及解决

    Thinkphp5图片上传正常,音频和视频上传失败的原因及解决 一.总结 一句话总结:php中默认限制了上传文件的大小为2M,查找错误的时候百度,且根据错误提示来查找错误. 我的实际问题是: 我的表单 ...

  5. PHP-02.文件上传、php保存/转移上传的文件、常见的网络传输协议、请求报文及属性、响应报文及属性

    关系数组 array("key"=>"value",...) ; get没有数据大小的限制 post上传大小没有限制 不指定上传方式,默认是get 文件上 ...

  6. 文件上传和下载(可批量上传)——Spring(三)

    在文件上传和下载(可批量上传)——Spring(二)的基础上,发现了文件下载时,只有在Chrome浏览器下文件名正常显示,还有发布到服务器后,不能上传到指定的文件夹目录,如上传20160310.txt ...

  7. 基于bootstrap的上传插件fileinput实现ajax异步上传功能(支持多文件上传预览拖拽)

    首先需要导入一些js和css文件 ? 1 2 3 4 5 6 <link href="__PUBLIC__/CSS/bootstrap.css" rel="exte ...

  8. jQuery文件上传插件jQuery Upload File 有上传进度条

    jQuery文件上传插件jQuery Upload File 有上传进度条 jQuery文件上传插件jQuery Upload File,插件使用简单,支持单文件和多文件上传,支持文件拖拽上传,有进度 ...

  9. [转]linux将一个服务器上的文件或者文件夹复制到另一台服务器上

    本文转载自<linux 将一个服务器上的文件或者文件夹复制到另一台服务器上>,有时间实践一把 使用scp将一个Linux系统中的文件或文件夹复制到另一台Linux服务器上 复制文件或文件夹 ...

随机推荐

  1. 「SAP技术」已启用质检物料创建PO时候'STOCK TYPE'没有默认为X?

    「SAP技术」 SAP MM 已启用质检物料创建PO时候'STOCK TYPE'没有默认为X? Part I:SAP 标准行为 1, 物料11002335, QM视图里 01 inspection t ...

  2. SAP系统邮件功能配置

    相信SAP顾问或多或少都会接到用户要求SAP系统能够定时发送邮件的功能,定时将用户需要的信息已邮件的方式发送给固定的人员. 下面就来讲一下SAP发送邮件应该如何配置: 1.RZ10做配置: is/SM ...

  3. The PostgreSQL installation in windows

    Summary: in this tutorial, we will show you how to install PostgreSQL on your local system for learn ...

  4. Violet音乐社区需求分析说明书

    目录 一.引言 1.1 编写目的 1.2 开发背景 1.3 开发工具 二.项目需求 2.1 角色定义 2.2 模块划分 2.3 功能概述 2.4 数据流图 三.前端页面 四.软件要求 4.1 性能要求 ...

  5. Data Pump Export 数据泵导出因ORA-31693 ORA-02354 和 ORA-01555 错误且没有LOB损坏而失败 (Doc ID 1507116.1)

    Data Pump Export Fails With ORA-31693 ORA-02354 and ORA-01555 Errors And No LOB Corruption (Doc ID 1 ...

  6. nvprof 使用记录; 以及使用 nvprof 查看tensorflow-gpu 核函数运行记录

    最近需要使用 nvprof 此时cuda 程序运行的性能,下面对使用过程进行简要记录,进行备忘: 常用使用命令:nvprof --unified-memory-profiling off python ...

  7. Mysql—数据恢复

    根据.frm和.ibd文件恢复表结构和数据

  8. requests乱码问题

    有三种方法解决请求后乱码问题. 一:获取二进制数据,再利用str进行编码转换 url='http://music.baidu.com' r = requests.get(url) html=r.con ...

  9. acWing 825. 排队购物

    题目描述苏西小朋友和她的妈妈正在超市里购物,看着收银处排着的长长的队伍,她就想如何能够提高整体的服务质量呢? 已知,现在有n个人正在排队等待结账,每个人结账所花的时间都可能是不同的,第 i 个人的结账 ...

  10. LeetCode 5123. 字母组合迭代器 Iterator for Combination

    地址 https://leetcode-cn.com/contest/biweekly-contest-15/problems/iterator-for-combination/ 题目描述请你设计一个 ...