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

  说,我有一个需求,就是一个临时功能。由于工作开发问题,我们有一个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如何将图片文件上传到另外一台服务器上,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • PHP多个文件上传到服务器实例

    本文实例讲述了PHP多个文件上传到服务器的实现方法.对于多个文件同时上传到服务器的情况来说,我们需要使用到数组形式的参数传递及数据的遍历上传即可,具体的操作步骤分析如下: 一.实例说明 上传图片到服务器,是程序开发过程中必不可少的一个功能.它不但可以达到图片共享的目的,而且可以提高网站的访问量,丰富网站的内容.在本实例中,讲解如何通过POST方式实现多图片上传. 二.关键技术 多文件上传的关键是如何定义上传文件元素的名称及如何判断上传文件的数量.在本实例中,以数组的形式定义上传文件的名称(上传文

  • PHP实现微信图片上传到服务器的方法示例

    本文实例讲述了PHP实现微信图片上传到服务器的方法.分享给大家供大家参考,具体如下: $pic_img=trim( $postObj->PicUrl); if($type=="image"){ $pic_url=save_file_to_sever($pic_img,$fromUsername); } GetRootPath(){ $sRealPath = realpath('./'); $sSelfPath = $_SERVER['PHP_SELF']; $sSelfPath

  • 微信小程序图片选择、上传到服务器、预览(PHP)实现实例

    微信小程序图片选择.上传到服务器.预览(PHP)实现实例 小程序实现选择图片.预览图片.上传到开发者服务器上 后台使用的tp3.2 图片上传 请求时候的header参考时可以去掉(个人后台验证权限使用) 小程序前端代码: <view class="section"> <form bindsubmit="bindFormSubmit"> <textarea placeholder="请输入问题内容" name=&quo

  • php上传图片客户端和服务器端实现方法

    本文实例讲述了php上传图片客户端和服务器端实现方法.分享给大家供大家参考.具体如下: 前台表单代码 <form name="form1" method="post" action="admin_upfile.php" enctype="multipart/form-data"> <input type="file" name="pic"> <input t

  • PHP实现上传图片到 zimg 服务器

    最近我们项目需要一台图片服务器存储用户头像,我们使用 zimg 处理和存储图片,下面简单介绍一下如何使用 PHP 上传图片到 zimg,并获取相应图片的返回信息 使用 curl 库实现上传 根据 zimg 使用文档,我们想要让 zimg 返回 json 信息,就必须 raw_post 上传图片,下面是演示代码 $upload_url = 'http://192.168.0.99:5000/upload'; $image_file = './test.jpg'; // 获取图片后缀 $value

  • Android异步上传图片到PHP服务器

    原理 Android客户端模拟一个HTTP的Post请求到服务器端,服务器端接收相应的Post请求后,返回响应信息给给客户端. 背景 网上很多上传到java服务器上的,找了好久,找到了上传到php的了,思路跟我当初想的差不多,就是POST过去.废话不多说,直接上图看代码. php代码 <?php $target_path = "./upload/";//接收文件目录 $target_path = $target_path . basename( $_FILES['uploaded

  • Android将图片上传到php服务器的实例代码

    layout中很普通,就是两个button和一个ImageView <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height=&q

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

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

  • iOS 图片上传使用base64或者二进制流上传头像功能

    我们在写代码的时候经常会将头像进行上传服务器,上传头像图片我试过两种方式 一种方式就是使用base64字符串上传图片,这种形式我个人认为比较适合上传图片数量比较少的,比如上传头像,上传图片数量多的话,速度会慢些 另一种方式是使用二进制流进行上传图片,这种方式上传图片少或者数量多都没关系,速度也很快 demo地址:http://download.csdn.net/detail/tuwanli125/9340205 demo地址:  https://github.com/tuwanli/Pictur

  • PHP文件上传判断file是否己选择上传文件的方法

    本文实例讲述了PHP文件上传判断file是否己选择上传文件的方法.分享给大家供大家参考.具体方法如下: 一个合格的程序员在实现数据入库中时我们都会有一些非常严密的过滤与数据规则,像我们文件上传时在前段要判断用户是否选择上传文件同时在后台也可判断是否有上传的文件,本文实例即对此做一较为深入的分析. 如下html代码所示: 复制代码 代码如下: <form action="?" method="post" enctype='multipart/form-data'

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

    首先需要导入一些js和css文件 <link href="__PUBLIC__/CSS/bootstrap.css" rel="external nofollow" rel="stylesheet"> <link type="text/css" rel="stylesheet" href="__PUBLIC__/CSS/fileinput.css" rel="

  • JavaScript大文件上传的处理方法之切片上传

    目录 前言 切片后上传 生成hash 文件秒传 暂停上传 中断请求示例 添加暂停上传功能 恢复上传 添加功能总结 前言 本篇介绍了切片上传的基本实现方式(前端),以及实现切片上传后的一些附加功能,切片上传原理较为简单,代码注释比较清晰就不多赘述了,后面的附加功能介绍了实现原理,并贴出了在原本代码上的改进方式.有什么错误希望大佬可以指出,感激不尽. 切片后上传 切片上传的原理较为简单,即获取文件后切片,切片后整理好每个切片的参数并发请求即可. 下面直接上代码: HTML <template> &

  • Android 通过webservice上传多张图片到指定服务器详解

    Android 通过webservice上传多张图片到指定服务器详解 当你浏览这个的时候相信你对webservice的基本应用已经有一定的了解了,若是还没有明白的小伙伴,可以看我前面写的文章点击打开链接,这几天在开发一款app,需要上传图片到指定服务器吧,但是我刚开始以为在网上面应该有这样的好文章的吧,结果我在网络上找了好多代码,在传递图片的过程中,遇到各种bug,真是国人的东西就是喜欢复制别人的,自己不动手检验一下代码的正确性,哎,我也是无语了,然后我决定花点时间来填补一下这个空缺,写了这一片

  • android 上传aar到私有maven服务器的示例

    搞这个东西也是花了蛮长时间,主要还是对gradle中的groovy语言不熟悉所导致的,写下来,以防下次再入坑- 在gradle中新建task 如果你需要将某个module打包成aar,并上传到maven上去,需要在这个module下面的build.gradle文件中添加如下代码: 其中代码: apply plugin: 'maven' 表示我们要应用的插件. MAVEN_LOCAL_PATH表示maven服务器地址,packaging表示需要打包的类型,groupId:artifactId:ve

  • 在同一台服务器上配置多个Tomcat的方法

    如果要在一台服务器上配置多个Tomcat,主要就是要避免Tomcat服务器的端口冲突的问题.只需要修改CATALINA_HOME\conf\server.xml中的启动端口和连接端口就OK了! 下面我们把配置的详细过程写在下面,以供参考:(此例以配置三个Tomcat为例) 1. 下载apache-tomcat-7.0.63,下载地址:http://tomcat.apache.org/download-70.cgi下载下来的文件为apache-tomcat-7.0.63.zip. 2. 解压该压缩

  • 如何在一台服务器上实现多个web站点的方法

    摘要:Windows2000Server安装成功后,一般会启动一个默认的Web站点,为整个网络提供Internet服务.在中小型局域网中,服务器往往只有一台,但是一个Web站点显然又无法满足工作需要.那么,能否在一台服务器上设置多个Web站点(以下我们简称为"一机多站")呢?答案是肯定的,并有多种途径可以达到这一目的.我们知道,网络上的每一个Web站点都有一个惟一的身份标识,从而使客户机能够准确地访问.这一标识由三部分组成,即TCP端口号.IP地址和主机头名,要实现"一机多站

  • 在一台服务器上安装两个或多个mysql的实现步骤

    如何在一台服务器上安装两个或者更多个的mysql呢?下面是详细的操作步骤,一起来学习学习吧. 一.环境 mysql软件包: mysql-5.6.31.tar mysql-5.5.32.tar 操作系统环境: CentOS release 6.8 (Final) 二.系统规模 /mysqlsoft 用来存放mysql的各个程序 /mysqlsoft/mysql1 用来存放mysql-5.5.32.tar的安装程序 /mysqlsoft/mysql2 用来存放mysql-5.6.31.tar的安装程

随机推荐