当前位置:首页 > PHP教程 > php上传下载 > 列表

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

发布:smiling 来源: PHP粉丝网  添加日期:2021-12-12 15:35:04 浏览: 评论:0 

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

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

一、当下问题

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

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

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

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

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

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

  1. /**上传图片 
  2.   * @param Request $request 
  3.   */ 
  4.  public function uploadImg(Request $request){ 
  5.   $file = $request->file('image'); 
  6.   $type = $request->post('type', 0); 
  7.   // 移动到框架应用根目录/uploads/ 目录下 
  8.   $upload_path = config('common.upload_path'); 
  9.   switch ($type) { 
  10.    case 1://门店 
  11.     $path = $upload_path['shop_img']; 
  12.     break
  13.    case 2://投票活动 
  14.     $path = $upload_path['vote_img']; 
  15.     break
  16.    case 3://投票活动参赛图片 
  17.     $path = $upload_path['vote_contestant_img']; 
  18.     break
  19.    case 4://会员店铺logo图片 
  20.     $path = $upload_path['member_shop']; 
  21.     break
  22.    case 5://自营商品图片 
  23.     $path = $upload_path['self_goods']; 
  24.     break
  25.    default
  26.     $path = $upload_path['common']; 
  27.     break
  28.   } 
  29.   $save_path = env('root_path').$path
  30.   $info = $file->validate(['ext'=>'jpg,jpeg,png,gif'])->move($save_path); 
  31.   if($info){ 
  32.    $return = [ 
  33.     'extension' => $info->getExtension(), 
  34.     'image_path' => $path.$info->getSaveName(), 
  35.     'image_name' => $info->getFilename(), 
  36.    ]; 
  37.    $this->apiResult(CustomError::OPERATION_SUCCSESS, $return); 
  38.   }else
  39.    $this->apiResult(CustomError::OPERATION_FAILED, [], $file->getError()); 
  40.   } 
  41.  } 

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

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

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

  1. <?php 
  2. //1、HttpRequest 发送http请求 
  3. $request = new HttpRequest(); 
  4. $request->setUrl('http://jszapi.dev.jingjinglego.com/index.php/index/uploadImg'); 
  5. $request->setMethod(HTTP_METH_POST); 
  6.  
  7. $request->setHeaders(array
  8.  'cache-control' => 'no-cache'
  9.  'Connection' => 'keep-alive'
  10.  'Content-Length' => '39091'
  11.  'Content-Type' => 'multipart/form-data; boundary=--------------------------296608706222243058746908'
  12.  'Accept-Encoding' => 'gzip, deflate'
  13.  'Host' => 'jszapi.dev.jingjinglego.com'
  14.  'Postman-Token' => 'dc010150-b166-4dec-a33f-959a65c91c71,be7315cb-ae21-404f-89fa-dddf5973eb3a'
  15.  'Cache-Control' => 'no-cache'
  16.  'Accept' => '*/*'
  17.  'User-Agent' => 'PostmanRuntime/7.15.2'
  18.  'content-type' => 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' 
  19. )); 
  20.  
  21. $request->setBody('------WebKitFormBoundary7MA4YWxkTrZu0gW 
  22. Content-Disposition: form-data; name="image"; filename="785da43beca5a474.jpg" 
  23. Content-Type: image/jpeg 
  24.  
  25.  
  26. ------WebKitFormBoundary7MA4YWxkTrZu0gW--'); 
  27.  
  28. try { 
  29.  $response = $request->send(); 
  30.  
  31.  echo $response->getBody(); 
  32. } catch (HttpException $ex) { 
  33.  echo $ex
  34.  
  35. <?php 
  36. //2、pecl_http 需要开启PECL HTTP 扩展 
  37. $client = new http\Client; 
  38. $request = new http\Client\Request; 
  39.  
  40. $body = new http\Message\Body; 
  41. $body->addForm(NULL, array
  42.  array
  43.  'name' => 'image'
  44.  'type' => null, 
  45.  'file' => '/E:/MyBooks/网站图标/网站素材/785da43beca5a474.jpg'
  46.  'data' => null 
  47.  ) 
  48. )); 
  49.  
  50. $request->setRequestUrl('http://jszapi.dev.jingjinglego.com/index.php/index/uploadImg'); 
  51. $request->setRequestMethod('POST'); 
  52. $request->setBody($body); 
  53.  
  54. $request->setHeaders(array
  55.  'cache-control' => 'no-cache'
  56.  'Connection' => 'keep-alive'
  57.  'Content-Length' => '39091'
  58.  'Content-Type' => 'multipart/form-data; boundary=--------------------------296608706222243058746908'
  59.  'Accept-Encoding' => 'gzip, deflate'
  60.  'Host' => 'jszapi.dev.jingjinglego.com'
  61.  'Postman-Token' => 'dc010150-b166-4dec-a33f-959a65c91c71,3216cc22-be61-4d4b-8d41-c5178848b54f'
  62.  'Cache-Control' => 'no-cache'
  63.  'Accept' => '*/*'
  64.  'User-Agent' => 'PostmanRuntime/7.15.2' 
  65. )); 
  66.  
  67. $client->enqueue($request)->send(); 
  68. $response = $client->getResponse(); 
  69.  
  70. echo $response->getBody(); 
  71.  
  72. <?php 
  73. //3、cURL 是一个非常强大的开源库,支持很多协议,包括HTTP、FTP、TELNET等,我们使用它来发送HTTP请求。//它给我们带来的好处是可以通过灵活的选项设置不同的HTTP协议参数,并且支持HTTPS。CURL可以根据URL前缀是“HTTP” 还是“HTTPS”自动选择是否加密发送内容。 
  74.  
  75. $curl = curl_init(); 
  76.  
  77. curl_setopt_array($curlarray
  78.  CURLOPT_URL => "http://jszapi.dev.jingjinglego.com/index.php/index/uploadImg"
  79.  CURLOPT_RETURNTRANSFER => true, 
  80.  CURLOPT_ENCODING => ""
  81.  CURLOPT_MAXREDIRS => 10, 
  82.  CURLOPT_TIMEOUT => 30, 
  83.  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, 
  84.  CURLOPT_CUSTOMREQUEST => "POST"
  85.  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--"
  86.  CURLOPT_HTTPHEADER => array
  87.  "Accept: */*"
  88.  "Accept-Encoding: gzip, deflate"
  89.  "Cache-Control: no-cache"
  90.  "Connection: keep-alive"
  91.  "Content-Length: 39091"
  92.  "Content-Type: multipart/form-data; boundary=--------------------------296608706222243058746908"
  93.  "Host: jszapi.dev.jingjinglego.com"
  94.  "Postman-Token: dc010150-b166-4dec-a33f-959a65c91c71,982e059e-bd8b-4db9-83c4-3fd52c8ed82f"
  95.  "User-Agent: PostmanRuntime/7.15.2"
  96.  "cache-control: no-cache"
  97.  "content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" 
  98.  ), 
  99. )); 
  100.  
  101. $response = curl_exec($curl); 
  102. $err = curl_error($curl); 
  103.  
  104. curl_close($curl); 
  105.  
  106. if ($err) { 
  107.  echo "cURL Error #:" . $err
  108. else { 
  109.  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项目,然后返回图片路径,不就可以了吗。于是我有推了一遍,发现没有疏忽。于是觉得应该是解决了。

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

三、解决图片上传问题

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

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

2、并转换成base64字符串,

  1. /** 
  2.  * 获取图片的Base64编码(不支持url) 
  3.  * @param $img_file 传入本地图片地址 
  4.  * @return string 
  5.  */ 
  6. function imgToBase64($img_file) { 
  7.  $img_base64 = ''
  8.  if (file_exists($img_file)) { 
  9.   $app_img_file = $img_file// 图片路径 
  10.   $img_info = getimagesize($app_img_file); // 取得图片的大小,类型等 
  11.   //echo '<pre>' . print_r($img_info, true) . '</pre><br>'; 
  12.   $fp = fopen($app_img_file"r"); // 图片是否可读权限 
  13.   if ($fp) { 
  14.    $filesize = filesize($app_img_file); 
  15.    $content = fread($fp$filesize); 
  16.    $file_content = chunk_split(base64_encode($content)); // base64编码 
  17.    switch ($img_info[2]) {   //判读图片类型 
  18.     case 1: $img_type = "gif"
  19.      break
  20.     case 2: $img_type = "jpg"
  21.      break
  22.     case 3: $img_type = "png"
  23.      break
  24.    } 
  25.    $img_base64 = 'data:image/' . $img_type . ';base64,' . $file_content;//合成图片的base64编码 
  26.   } 
  27.   fclose($fp); 
  28.  } 
  29.  return $img_base64//返回图片的base64 

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

  1. /** 
  2.   * 将base64字符串转换成图片并保存在本地 
  3.   * @param Request $request 
  4.   * @return void 
  5.   */ 
  6.  public function baseImg(Request $request
  7.  { 
  8.   $base_string = $request->post('base_string'''); 
  9.   if (!$base_string) { 
  10.    $this->apiResult(CustomError::MISSING_PARAMS); 
  11.   } 
  12.   $path = $request->post('path'''); 
  13.   if (!$path) { 
  14.    $this->apiResult(CustomError::MISSING_PARAMS); 
  15.   } 
  16.   $request = base64_image_content($base_string$path);//解码 
  17.   if($request){ 
  18.    $this->apiResult(CustomError::OPERATION_SUCCSESS, $request); 
  19.   }else
  20.    $this->apiResult(CustomError::OPERATION_FAILED); 
  21.   } 
  22.  } 

4、对字符解析解码

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

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

:结束

Tags: PHP图片文件上传

分享到: