简体   繁体   中英

Downloading a folder with phpseclib Net_SFTP.get does not work

I am trying to access a file in an SFTP folder server using phpseclib. But when I try using $sftp->get , it returns false . I am not sure how to debug the problem at all.

public function get_file_from_ftps_server()
{
    $sftp = new \phpseclib\Net\SFTP(getenv('INSTRUM_SERVER'));
    if (!$sftp->login(getenv('INSTRUM_USERNAME'), getenv('INSTRUM_PASSWORD'))) {
        exit('Login Failed');
    }

    $this->load->helper('file');           
    $root  = dirname(dirname(__FILE__));
    $root .= '/third_party/collections_get/';
    $path_to_server = 'testdownload/';
    $result = $sftp->get($path_to_server, $root);

    var_dump($result);
}

In the $result , I get a false and I am not sure why its happening, I read their documentation but still not sure. Root is the directory where I want my information to be stored. Right now I only added a trial.xml file there, but also wondering how can I get multiple files if its in the folder.

Here is a picture of the server structure:

结构体

Normally when I use sftp , I normally change directory and then try to download the information.

$sftp->pwd(); // This will show you are in the root after connection.
$sftp->chdir('./testdownload'); // this will go inside the test directory.
$get_path = $sftp->pwd()
//If you want to download multiple data, use
$x = $sftp->nlist();
//Loop through `x` and then download the file using.
$result = $sftp->get($get_path); // Normally I use the string information that is returned and then download using

file_put_contents($root, $result);

// Root is your directory, and result is the string.

The Net_SFTP.get method can download a single file only. You cannot use it to download a whole directory.

If you want to download whole directory, you have to use one of the "list" methods ( Net_SFTP.nlist or Net_SFTP.rawlist ) to retrieve list of files and then download the files one-by-one.

<?php
use phpseclib\Net\SFTP;

$sftp = new SFTP("server");

if(!$sftp->login("username", "password")) {
    throw new Exception("Connection failed");
}

// The directory you want to download the contents of
$sftp->chdir("/remote/system/path/");

// Loop through each file and download
foreach($sftp->nlist() as $file) {
    if($file != "." && $file != "..")
        $sftp->get("/remote/system/path/$file", "/local/system/path/$file");
}
?>

Im a bit late but none te less i wanted to share this. The approach i take is to use zip files to download folder the reason for this is that you will have an feedback that something is being downloaded.

If you don't want that simply remove the things related to zip as well remove the headers and replace them with $sftp->get("remote/file", "local/file");

<?PHP
use phpseclib\Net\SFTP;

$sftp = new SFTP("IP:Port");

if(!$sftp->login("username", "password")) throw new Exception("Connection failed");

# Create directory variable
$directory =  "/remote/path/";

# Set directory
$sftp->chdir($directory);

# File Name
$name =  'file';

# Retrieve file
$file = $sftp->get('file');

# Check if is folder
if ($sftp->is_dir($file)) {

  # Temporarily file
  $tmp = sys_get_temp_dir()."\\yourSite_".rand().".zip";

  # Create new Zip Archive.
  $zip = new ZipArchive();  

  # Open new Zip file
  $zip->open($tmp,  ZipArchive::CREATE | ZipArchive::OVERWRITE);

  function recursive($src, $zip, $sftp) {

    # Loop Through files
    foreach ($sftp->nlist($src) as $file) {

        # Skip . & ..
        if ($file == "." || $file == "..") continue;

        if (!$sftp->is_file($src . "/" . $file)) {

        # Make directory
        $zip->addEmptyDir($src . "/" . $file);

        # Run the loop again
        recursive($src . "/" . $file, $zip, $sftp);

      } else {
          # Add file to zip within folder
          $zip->addFromString($src . "/" . $file,  $sftp->get($src));

      }

    }

  }

  # Run Recursive loop
  recursive($name, $zip, $sftp);

  # Close zip file
  $zip->close();

  header('Content-Description', 'File Transfer');
  header('Content-type', 'application/zip');
  header('Content-Disposition', 'attachment; filename="' . $name . '.zip"');
  header('Content-length', filesize($tmp));

  echo file_get_contents($tmp);

  unlink($tmp);
  return;

}

# Otherwise download single file
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=\"". $name ."\"");

echo $file;
return;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM