【问题标题】:Downloading a folder through with FTP using PHP使用 PHP 通过 FTP 下载文件夹
【发布时间】:2011-08-04 18:14:07
【问题描述】:

如何使用 FTP 和 PHP 从远程主机下载文件夹?

我有用户名和密码以及要下载的文件夹...

复制()?

告诉我,谢谢!

【问题讨论】:

  • 你检查了this

标签: php ftp directory


【解决方案1】:

您可以在 PHP 中使用 FTP 功能:

http://www.php.net/manual/en/ref.ftp.php

编辑:

另见:PHP download entire folder (recursive) via FTP

【讨论】:

    【解决方案2】:
    <?php 
    $ftp_server = "ftp.example.com"; 
    $conn_id = ftp_connect ($ftp_server) 
        or die("Couldn't connect to $ftp_server"); 
        
    $login_result = ftp_login($conn_id, "user", "pass"); 
    if ((!$conn_id) || (!$login_result)) 
        die("FTP Connection Failed"); 
    
    ftp_sync ("DirectoryToCopy");    // Use "." if you are in the current directory 
    
    ftp_close($conn_id);  
    
    // ftp_sync - Copy directory and file structure 
    function ftp_sync ($dir) { 
    
        global $conn_id; 
    
        if ($dir != ".") { 
            if (ftp_chdir($conn_id, $dir) == false) { 
                echo ("Change Dir Failed: $dir<BR>\r\n"); 
                return; 
            } 
            if (!(is_dir($dir))) 
                mkdir($dir); 
            chdir ($dir); 
        } 
    
        $contents = ftp_nlist($conn_id, "."); 
        foreach ($contents as $file) { 
        
            if ($file == '.' || $file == '..') 
                continue; 
            
            if (@ftp_chdir($conn_id, $file)) { 
                ftp_chdir ($conn_id, ".."); 
                ftp_sync ($file); 
            } 
            else 
                ftp_get($conn_id, $file, $file, FTP_BINARY); 
        } 
            
        ftp_chdir ($conn_id, ".."); 
        chdir (".."); 
    
    } 
    ?>
    

    来源:https://www.php.net/manual/function.ftp-get.php#90910

    【讨论】:

    【解决方案3】:

    你有这些选择:

    • ftp 包装器:

      $handle = opendir('ftp://user:password@host/path/to/dir') || die();
      
      while (false !== ($file = readdir($handle))) {
        if(is_file($file)){
          $c = file_get_contents($file);
          file_put_contents('/local/'.basename($file), $c);
        }
      }
      
      closedir($handle);
      
    • 使用php的ftp扩展

      $c = ftp_connect('host.com');
      ftp_login($c, 'file', 'password');
      ftp_chdir($c, '/remote/dir');
      $contents = ftp_nlist($c, '-la .');
      foreach($contents as $line){
        $file = preg_split('@\s+@', trim($line));
        $name = $file[8];
        $size = $file[4];
        $mode = $file[0];
        if(substr($mode, 0, 1) == '-'){
          //file
          $fd = fopen('/local/path/'.$name, 'w');
          ftp_fget ($c, $fd, $name, FTP_BINARY);
          fclose($fd);
        }else{
          //dir
        }
      }
      
    • 使用 wget 或 lftp 等外部程序

      • wget --recursive [选项] ftp://user:password@host/ # 见 wget --help
      • lftp -c commands.txt # 其中 commands.txt 会是这样的:

        connect user:password@ftp.host.com
        mget /path/to/remote /path/to/local
        

    【讨论】:

      【解决方案4】:

      我刚刚在FTPSFTP 发布了两个新的库来做这些事情。

      递归复制远程 SFTP 服务器上的文件和文件夹(如果 local_path 以斜线结尾,则上传文件夹内容,否则上传文件夹本身)

      Ftp::upload_dir($server, $user, $password, $local_path, $remote_path, $port = 22);
      

      从远程 FTP 服务器下载目录(如果 remote_dir 以斜线结尾下载文件夹内容,否则下载文件夹本身)

      Ftp::download_dir($server, $user, $password, $remote_dir, $local_dir, $port = 22);
      

      对于这里的代码,但您需要整个类来实现小型实用程序函数依赖项。

      /**
       * Download a directory from remote FTP server
       *
       * If remote_dir ends with a slash download folder content
       * otherwise download folder itself
       *
       * @param string $server 
       * @param string $user
       * @param string $password
       * @param string $remote_dir
       * @param string $local_dir
       * @param int $port
       *
       * @return bool $downloaded
       *
       */
      public static function download_dir($server, $user, $password, $remote_dir, $local_dir, $port = 21)
      {
          $downloaded = false;
          try
          {
              if(is_dir($local_dir) && is_writable($local_dir))
              {
                  if(false !== $cid = Ftp::login($server, $user, $password, $port))
                  {
                      # If remote_dir do not ends with /
                      if(!HString::ends_with($remote_dir, '/'))
                      {
                          # Create fisrt level directory on local filesystem
                          $local_dir = rtrim($local_dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . basename($remote_dir);
                          mkdir($local_dir);
                      }
      
                      # Remove trailing slash
                      $local_dir = rtrim($local_dir, DIRECTORY_SEPARATOR);
                      $downloaded = Ftp::download_all($cid, $remote_dir, $local_dir); 
                      ftp_close($cid); 
                  }
              }
              else
              {
                  throw new Exception("Local directory does not exist or is not writable", 1);
              }
          }
          catch(Exception $e)
          {
              error_log("Ftp::download_dir : " . $e->getMessage());
          }
          return $downloaded;
      }
      /**
       * Recursive function to download remote files
       *
       * @param ressource $cid
       * @param string $remote_dir
       * @param string $local_dir
       *
       * @return bool $download_all
       *
       */
      private static function download_all($cid, $remote_dir, $local_dir)
      {
          $download_all = false;
          try
          {
              if(Ftp::is_dir($remote_dir, $cid))
              {
                  $files = ftp_nlist($cid, $remote_dir);
                  if($files!==false)
                  {
                      $to_download = 0;
                      $downloaded = 0;
                      # do this for each file in the remote directory 
                      foreach ($files as $file)
                      {
                          # To prevent an infinite loop 
                          if ($file != "." && $file != "..")
                          {
                              $to_download++;
                              # do the following if it is a directory 
                              if (Ftp::is_dir($file, $cid))// $remote_dir . DIRECTORY_SEPARATOR .
                              {                                
                                  # Create directory on local filesystem
                                  mkdir($local_dir . DIRECTORY_SEPARATOR . basename($file));
      
                                  # Recursive part 
                                  if(Ftp::download_all($cid, $file, $local_dir . DIRECTORY_SEPARATOR . basename($file)))
                                  {
                                      $downloaded++;
                                  }
                              }
                              else
                              { 
                                  # Download files 
                                  if(ftp_get($cid, $local_dir . DIRECTORY_SEPARATOR . basename($file), $file, FTP_BINARY))
                                  {
                                      $downloaded++;
                                  }
                              } 
                          }
                      }
                      # Check all files and folders have been downloaded
                      if($to_download===$downloaded)
                      {
                          $download_all = true;
                      }
                  }
              }
          }
          catch(Exception $e)
          {
              error_log("Ftp::download_all : " . $e->getMessage());
          }
          return $download_all;
      }
      

      【讨论】:

      • 致命错误:未捕获错误:找不到类“Hug\HString\HString”
      • @BhaveshPrajapati 你不应该复制/粘贴上面的代码,而是像库存储库中描述的那样通过作曲家安装它来安装依赖项......
      【解决方案5】:

      改进的功能来自@Treffynnon

      • 已改进,因为当文件夹中有 100 多个文件时,ftp_chdir() 非常耗时
      • 将传输隐藏文件,如 .htaccess
      • 仅在需要时复制(检查存在且最后修改)

      <?php
      $ftp_server = "ftp.xxx.com"; 
      $cid = ftp_connect($ftp_server) 
          or die("Couldn't connect to $ftp_server"); 
      
      $login_result = ftp_login($cid, "user", "pass"); 
      if ((!$cid) || (!$login_result)) 
          die("FTP Connection Failed"); 
      
      ftp_pasv($cid, true); // passive FTP connection (comment-out if needed)
      
      ftp_sync('/folder_on_ftp/www/', '/folder_on_new_server/www');
      
      ftp_close($cid);
      
      umask(0); // every directory will be chmod 777
      
      function ftp_sync($_from = null, $_to = null) {
          
          global $cid;
          
          if (isset($_from)) {
              if (!ftp_chdir($cid, $_from)) die("Dir on FTP not found: $_from");
              if (isset($_to)) {
                  if (!is_dir($_to)) @mkdir($_to);
                  if (!chdir($_to)) die("Dir on local not exists? $_to"); 
              }
          }
          
          $contents = ftp_mlsd($cid, '.');
          
          foreach ($contents as $p) {
              
              if ($p['type'] != 'dir' && $p['type'] != 'file') continue;
              
              $file = $p['name'];
              
              echo ftp_pwd($cid).'/'.$file;
              
              if (file_exists($file) && !is_dir($file) && filemtime($file) >= strtotime($p['modify'])) {
                  echo " [EXISTS AND CURRENT]";
              }
              elseif ($p['type'] == 'file' && @ftp_get($cid, $file, $file, FTP_BINARY)) {
                  echo " [COPIED]";
              }
              elseif ($p['type'] == 'dir' && @ftp_chdir($cid, $file)) {
                  echo "Dir changed to $file<br>\n";
                  if (!is_dir($file)) mkdir($file);
                  chdir($file);
                  ftp_sync();
                  ftp_chdir($cid, '..');
                  chdir('..');
              }
              
              echo "<br>\n";
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2011-08-02
        • 2011-03-19
        • 1970-01-01
        • 2012-10-04
        • 1970-01-01
        • 2012-01-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多