【问题标题】:PHP: upload file from one server to another serverPHP:将文件从一台服务器上传到另一台服务器
【发布时间】:2016-02-10 09:19:42
【问题描述】:

我正在服务器中开发一个网站,而存储在另一台服务器中,我必须以某种方式处理它。这个案例我用心体验了一下,发现解决办法就是使用curl。

请从零开始详细讲解Curl的使用方法。

更新:

我使用以下代码测试是否安装并启用了 cURL:

<?PHP
phpinfo(); 

$toCheckURL = "http://board/accSystem/webroot/";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $toCheckURL);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
$data = curl_exec($ch);
curl_close($ch);
preg_match_all("/HTTP\/1\.[1|0]\s(\d{3})/",$data,$matches);
$code = end($matches[1]);
if(!$data) {
  echo "Domain could not be found";
} else {
  switch($code) {
    case '200':
      echo "Page Found";
      break;
    case '401':
      echo "Unauthorized";
      break;
    case '403':
      echo "Forbidden";
      break;
    case '404':
      echo "Page Not Found";
      break;
    case '500':
      echo "Internal Server Error";
      break;
  }
}
?>

结果如下:

我收到(找到页面)消息

现在我可以放心使用 cURL 了吧?

注意: 两台服务器都是本地的

【问题讨论】:

  • 更头疼的是我想检索上传的文件并查看并更新它(用另一个文件替换它)并删除它:")
  • 我想帮忙,但我认为我们需要更多信息。说你想通过curl从另一个服务器检索一个文件并修改它,嗯,有点模糊。

标签: post curl file-upload


【解决方案1】:

作为一名 PHP 开发人员,您可能已经熟悉 PHP 最方便的文件系统函数 fopen。该函数打开一个文件流并返回一个资源,然后可以将其传递给 fread 或 fwrite 以读取或写入数据。有些人没有意识到文件资源不一定要指向本地机器上的某个位置。

这是一个将文件从本地服务器传输到 ftp 服务器的示例:

$file = "filename.jpg";
$dest = fopen("ftp://username:password@example.com/" . $file, "wb");
$src = file_get_contents($file);
fwrite($dest, $src, strlen($src));
fclose($dest); 

可以在 PHP 手册的附录 M 中找到支持的不同协议的列表。您可能希望使用采用某种加密机制的协议,例如 FTPS 或 SSH,具体取决于网络设置和您要移动的信息的敏感性。

curl 扩展使用客户端 URL 库 (libcurl) 来传输文件。实现 curl 方案的逻辑一般如下:首先初始化会话,设置所需的传输选项,执行传输,然后关闭会话。

使用 curl_init 函数初始化 curl 会话。该函数返回一个可以与其他 curl 函数一起使用的资源,就像在文件系统函数中使用 fopen 获取资源一样。

传输会话的上传目标和其他方面是使用 curl_setopt 设置的,curl 资源是一个预定义的常量,表示设置和选项的值。

这是一个使用 HTTP 协议的 PUT 方法将文件从本地主机传输到远程服务器的示例:

$file = "testfile.txt";

$c = curl_init();
curl_setopt($c, CURLOPT_URL, "http://example.com/putscript");
curl_setopt($c, CURLOPT_USERPWD, "username:password");
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_PUT, true);
curl_setopt($c, CURLOPT_INFILESIZE, filesize($file));

$fp = fopen($file, "r");
curl_setopt($c, CURLOPT_INFILE, $fp);

curl_exec($c);

curl_close($c);
fclose($fp); 

可以在 php 文档中找到 curl 的有效选项列表。

ftp 扩展允许您实现对 ftp 服务器的客户端访问。当前两个选项可用时,使用 ftp 传输文件可能是矫枉过正......理想情况下,最好使用这个扩展,需要更高级的功能。

使用 ftp_connect 与 ftp 服务器建立连接。您可以使用 ftp_login 通过提供用户名和密码来验证与 ftp 服务器的会话。使用 ftp_put 函数将该文件放置在远程服务器上。它接受目标文件名、本地源文件名和预定义的常量来指定传输模式:FTP_ASCII 用于纯文本传输或 FTP_BINARY 用于二进制传输。传输完成后,使用 ftp_close 释放资源并终止 ftp 会话。

$ftp = ftp_connect("ftp.example.com");
ftp_login($ftp, "username", "password");
ftp_put($ftp, "destfile.zip", "srcfile.zip", FTP_BINARY); 
ftp_close($ftp); 

【讨论】:

  • 从技术上讲,第一个选项不也是 FTP 吗?实际的 FTP 扩展如何更矫枉过正?
【解决方案2】:

我们使用与您相同的用例。我们有两个服务器:应用服务器和存储服务器。应用服务器包含方法和 UI 部分,存储服务器是我们上传文件的地方。以下是我们用于文件上传的地方,它工作正常:

1) 您必须在您的存储服务器上添加一个包含以下方法的 php 文件:

<?php
switch ($_POST['calling_method']) {    
case 'upload_file':
    echo uploadFile();
    break;
case 'delete':
    return deleteFile();
    break;    
}

function uploadFile() {
   $localFile = $_FILES['file']['tmp_name'];

   if (!file_exists($_POST['destination'])) {
     mkdir($_POST['destination'], 0777, true);
   }

   $destination = $_POST['destination'] . '/' . $_FILES['file']['name'];
   if (isset($_POST['file_name'])) {
      $destination = $_POST['destination'] . '/' . $_POST['file_name'];
   }
   $moved = move_uploaded_file($localFile, $destination);

   if (isset($_POST['file_name'])) {
    chmod($destination, 0777);
   }
   $result['message'] = $moved ? 'success' : 'fail';
   echo json_encode($result);
 }

function deleteFile() {
   if (file_exists($_POST['file_to_be_deleted'])) {
     $res = unlink($_POST['file_to_be_deleted']);
     return $res;
   }
  return FALSE;
}
?>

2) 在您的应用服务器上。

创建一个将 $_FILES 数据传递到存储服务器的方法。

 $data = array(
    'file' => new CURLFile($_FILES['file']['tmp_name'],$_FILES['file']['type'], $_FILES['file']['name']),
    'destination' => 'destination path in which file will be uploaded',
    'calling_method' => 'upload_file',
    'file_name' => 'file name, you want to give when upload will completed'
); 

**Note :CURLFile class will work if you have PHP version >= 5**

 $ch = curl_init();

curl_setopt($ch, CURLOPT_URL, PATH_FOR_THAT_PHP_FILE_ON_STORAGE_SERVER_FILE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_TIMEOUT, 86400); // 1 Day Timeout
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60000);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_REFERER, $_SERVER['HTTP_HOST']);

$response = curl_exec($ch);
if (curl_errno($ch)) {

    $msg = FALSE;
} else {
    $msg = $response;
}

curl_close($ch);
echo $msg;

这种方式使用CURL会调用存储服务器文件方法并上传文件,同样的方式你可以调用方法删除文件。

希望这会有所帮助。

【讨论】:

    【解决方案3】:

    你可以谷歌一下,有很多关于如何使用 curl 的教程。在您的情况下,您需要在两台服务器上开发两个部分:

    1. 接收表格,等待上传的文件(接收方)
    2. 卷曲上传脚本(发件人)

    发件人脚本可能是相似的:

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, array('file' => '@/path/to/file.txt'));
    curl_setopt($ch, CURLOPT_URL, 'http://yoursecondserver.com/upload.php');
    curl_exec($ch);
    curl_close($ch);
    

    如何在第二台服务器上接收文件,你可以在 PHP 手册中阅读,很多例子http://php.net/manual/en/features.file-upload.php

    您可能想要使用 FTP 连接,如果将它安装在您的服务器上,它可能会更容易。

    【讨论】:

      【解决方案4】:

      在这种情况下,您可以使用本地服务器上的文件路径在远程服务器上调用 PHP 脚本。 然后在远程服务器上使用 file_get_contents 保存文件。 本地服务器上的示例:

      <?php
      file_get_contents('http://somestaticfilesserver.com/download.php?file=path/to/some/file.png')
      

      download.php 看起来像这样:

      <?php
      $remoteHost = 'http://serversendingfile.com';
      $rootPath = realpath(__DIR__) . DIRECTORY_SEPARATOR . 'uploaded' . DIRECTORY_SEPARATOR;
      $filePath = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, filter_input_array(INPUT_GET)['file']);
      $fileName = (basename($filePath));
      $remoteFile = $remoteHost . $filePath;
      $file = file_get_contents($remoteFile);
      $absolutePath = str_replace($fileName, '', $rootPath . $filePath);
      if (!is_dir($absolutePath)) {
          mkdir($absolutePath, 0777, true);
      }
      if (file_put_contents($absolutePath . $fileName, $file, FILE_APPEND)) {
          die('ok');
      }
      die('nok');
      

      给定的路径将保持相对于 $rootPath

      【讨论】:

        【解决方案5】:

        首先,确保其他服务器将接受您的连接,查找跨域策略问题。此外,请确保该文件是公开可用的(即:您可以通过使用标准浏览器导航到 URL 来下载它)。

        一切都设置好后,您可以使用file_get_contents 获取文件内容并使用file_put_contents 将其保存在本地:

        file_put_contents('file_name', file_get_contents('FILE_URL'));

        您的其他问题(删除、编辑)确实是一个不同的问题,很可能应该在他们自己的问题中处理,因为出于明显的安全原因,无法单独从您的网站服务器执行此操作。 您需要在存储服务器上公开一个 API 并从网站访问该 API,以使存储执行操作成为适当的操作。

        【讨论】:

          【解决方案6】:

          您可以通过发布文件将文件上传到另一台服务器。

          $request = curl_init('http://example.com/');
          
          // send a file
          curl_setopt($request, CURLOPT_POST, true);
          curl_setopt(
              $request,
              CURLOPT_POSTFIELDS,
              array(
                'file' => '@' . realpath('example.txt')
              ));
          
          curl_setopt($request, CURLOPT_RETURNTRANSFER, true);
          echo curl_exec($request);
          
          curl_close($request);
          

          您可以使用 $_FILES['file'] 处理上传的文件

          【讨论】:

            猜你喜欢
            • 2011-11-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-12-03
            • 2015-09-30
            • 2017-01-23
            • 1970-01-01
            • 2016-10-18
            相关资源
            最近更新 更多