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


Posted in PHP onAugust 26, 2019

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

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

一、当下问题

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

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

// [ 应用入口文件 ]
//入口文件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,发现确实没有什么问题,于是就准备如此处理。

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

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项目,然后返回图片路径,不就可以了吗。于是我有推了一遍,发现没有疏忽。于是觉得应该是解决了。

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

三、解决图片上传问题

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

PHP 相关文章推荐
关于文本留言本的分页代码
Oct 09 PHP
PHP CURL模拟GET及POST函数代码
Apr 25 PHP
preg_match_all使用心得分享
Jan 31 PHP
兼容ie6浏览器的php下载文件代码分享
Jul 14 PHP
调用WordPress函数统计文章访问量及PHP原生计数器的实现
Mar 21 PHP
Windows Server 2008 R2和2012中PHP连接MySQL过慢的解决方法
Jul 02 PHP
PHP入门教程之自定义函数用法详解(创建,调用,变量,参数,返回值等)
Sep 11 PHP
php自定义扩展名获取函数示例
Dec 12 PHP
Yii框架实现多数据库配置和操作的方法
May 25 PHP
PHP7匿名类的用法示例
Apr 05 PHP
php+jQuery ajax实现的实时刷新显示数据功能示例
Sep 12 PHP
PHP+fiddler抓包采集微信文章阅读数点赞数的思路详解
Dec 20 PHP
PHP命名空间与自动加载机制的基础介绍
Aug 25 #PHP
php的命名空间与自动加载实现方法
Aug 25 #PHP
PHP7数组的底层实现示例
Aug 25 #PHP
PHP实现cookie跨域session共享的方法分析
Aug 23 #PHP
php常用经典函数集锦【数组、字符串、栈、队列、排序等】
Aug 23 #PHP
php中错误处理操作实例分析
Aug 23 #PHP
php+js实现的无刷新下载文件功能示例
Aug 23 #PHP
You might like
php获取网页内容方法总结
2008/12/04 PHP
PHP 文件上传功能实现代码
2009/06/24 PHP
一个简单至极的PHP缓存类代码
2015/10/23 PHP
PHP5.3新特性小结
2016/02/14 PHP
Zend Studio使用技巧两则
2016/04/01 PHP
PHP获取表单数据与HTML嵌入PHP脚本的实现
2017/02/09 PHP
PHP的PDO大对象(LOBs)
2019/01/27 PHP
JQuery在光标位置插入内容的实现代码
2010/06/18 Javascript
JQuery小知识
2010/10/15 Javascript
JS中获取数据库中的值的方法
2013/07/14 Javascript
javascript静态页面传值的三种方法分享
2013/11/12 Javascript
JQuery获取或设置ckeditor的数据(示例代码)
2013/11/15 Javascript
document.addEventListener使用介绍
2014/03/07 Javascript
Vue数据驱动模拟实现1
2017/01/11 Javascript
AngularJs表单校验功能实例代码
2017/02/09 Javascript
jQuery上传插件webupload使用方法
2017/08/01 jQuery
vue项目国际化vue-i18n的安装使用教程
2018/03/14 Javascript
浅谈js中的bind
2019/03/18 Javascript
微信小程序自定义tabBar在uni-app的适配详解
2019/09/30 Javascript
微信小程序分享小程序码的生成(带参数)以及参数的获取
2020/03/25 Javascript
python递归计算N!的方法
2015/05/05 Python
python开发之list操作实例分析
2016/02/22 Python
python3.6+django2.0开发一套学员管理系统
2018/03/03 Python
Python针对给定字符串求解所有子序列是否为回文序列的方法
2018/04/21 Python
Python装饰器原理与用法分析
2018/04/30 Python
Python实现抓取HTML网页并以PDF文件形式保存的方法
2018/05/08 Python
python 实现图片批量压缩的示例
2020/12/18 Python
解决Firefox下不支持outerHTML问题代码分享
2014/06/04 HTML / CSS
Skyscanner阿联酋:全球领先的旅游搜索平台
2017/11/25 全球购物
购买正版游戏和游戏激活码:Green Man Gaming
2019/11/06 全球购物
大学毕业生工作的自我评价
2013/10/01 职场文书
养生餐厅创业计划书范文
2014/03/26 职场文书
房屋所有权证明
2014/10/20 职场文书
导游词之云南省玉龙雪山
2019/12/19 职场文书
Python之Matplotlib绘制热力图和面积图
2022/04/13 Python
Windows server 2012 R2 安装IIS服务器
2022/04/29 Servers