侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

PHP如何将图片文件上传到另外一台服务器上

php  /  管理员 发布于 7年前   281

  说,我有一个需求,就是一个临时功能。由于工作开发问题,我们有一个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给我提供了三种,调取接口的方式。

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('------WebKitFormBoundary7MA4YWxkTrZu0gWContent-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;}

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();
 "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的参数很容易看懂,但是运用的话需要开启扩展,这个目前不太合适,所以┭┮n┭┮。

二、写在心里

  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 '
' . print_r($img_info, true) . '

'; $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如何将图片文件上传到另外一台服务器上,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

您可能感兴趣的文章:

  • Android将图片上传到php服务器的实例代码
  • PHP实现微信图片上传到服务器的方法示例
  • 微信小程序图片选择、上传到服务器、预览(PHP)实现实例
  • PHP实现上传图片到 zimg 服务器
  • Android异步上传图片到PHP服务器
  • php上传图片客户端和服务器端实现方法
  • PHP多个文件上传到服务器实例


  • 上一条:
    php中的钩子理解及应用实例分析
    下一条:
    PHP命名空间与自动加载机制的基础介绍
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 用Time Warden监控PHP中的代码处理时间(0个评论)
    • 在PHP中使用array_pop + yield实现读取超大型目录功能示例(0个评论)
    • Property Hooks RFC在PHP 8.4中越来越接近现实(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-11
    • 2017-12
    • 2018-01
    • 2018-02
    • 2018-03
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-09
    • 2021-02
    • 2021-03
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    • 2024-05
    • 2024-06
    • 2024-07
    • 2024-09
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客