Masnad Nihit
Masnad Nihit

Reputation: 1996

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:

structure

Upvotes: 4

Views: 4943

Answers (4)

Frontliner
Frontliner

Reputation: 29

I'm a bit late but nonetheless I wanted to share this. The approach I take is to use zip files to download folders. The reason for this is that you will have a feedback that something is being downloaded.

If you don't want that, simply remove the things related to zip. Then, 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 . "/" . $file));

      }

    }

  }

  # 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);

  # Delete temporarily file
  unlink($tmp);
  return;

}

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

echo $file;
return;

Upvotes: 0

c0nfus3d
c0nfus3d

Reputation: 1440

<?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");
}
?>

Upvotes: 0

XAF
XAF

Reputation: 1472

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.

Upvotes: 3

Martin Prikryl
Martin Prikryl

Reputation: 202088

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.

Upvotes: 2

Related Questions