Re: Hoping for a working example of SFTP in PHP

[email protected] (David Spector)
Newsgroups php.general
Message-ID <[email protected]>
Dear R. Eric Wheeler,

Thank you! After several weeks of posting my question in several fora, 
you are the first to reply with an example that works. Thank you! I am 
so happy. After I have time to clean up the formatting and document it a 
bit more fully I plan to post it everywhere, since no one seemed to know 
how to make this simple and valuable example. I will give you credit, 
and you deserve it!

One minor problem: the file is uploaded to the document root instead of 
the $remoteDir directory. I can probably figure this out, but it would 
help if you correct my code. I may have messed something up.

Here is your code after I modified it to work in my environment. Note 
that I commented out your code to list the remote dir since it gave an 
error message and I don't need it anyway. If there are no errors 
detected, and it passes a simple test for successful upload once, I'm 
satisfied that the file was uploaded.

One question: what is the "copy" function there for? I don't think I 
need any files copied locally in order to upload a file.

One more question: can it work without knowing the user's password? I'm 
thinking of disabling passwords on my remote webserver, so access is by 
public/private keys only.

Thank you!

David

<?php declare(strict_types=1);
// From R. Eric Wheeler [email protected]

// Tested on
// PHP 7.4.14 (cli) (built: Jan  5 2021 15:12:29) ( ZTS Visual C++ 2017 
x64 )
// Windows 10 Pro
// pecl ssh2 v1.2

// Remote server
// Gentoo GNU/Linux Base System release 2.7

error_reporting(E_ALL);
ini_set('display_errors', '1');

$c=GetConfigArr("secret.json");
extract($c);

file_put_contents(__DIR__.'/test.txt', 'worked!');

$host = $hostIP;
$port = (int)$securePort;

$connection = ssh2_connect($host, $port); // let libssh2 figure it out.

if(!is_resource($connection)) {
     exit('Connection failed.');
}

// Without the __DIR__ php will just try to get 'id_rsa' and will fail.
// if your keys are elsewhere __DIR__ should be changed to 
C:\path\to\your\files
$privateKey = __DIR__.'\w.key'; // id_rsa
$publicKey = __DIR__.'\w1.pub'; // id_rsa.pub
$username = $user;
$passphrase = $passphrase; // set this to passphrase if you have one.

if(false === ssh2_auth_pubkey_file($connection, $username, $publicKey, 
$privateKey, $passphrase)) {
     ssh2_disconnect($connection);
     exit('Authentication failed.');
}

$sftp = ssh2_sftp($connection);
$streamUrl = sprintf("ssh2.sftp://%d", (int)$sftp);

$path = sprintf($remoteDir, $streamUrl);
$file = sprintf('%s/test.txt', $path);
$localFile = __DIR__ . '/test.txt';

if(!file_exists($file)) {
     if(true === copy($localFile, $file)) {
         print 'Successfully copied ' . $localFile . PHP_EOL;
     }
} else {
     print 'File exists' . PHP_EOL;
}

// using ssh2_scp_send, if all you need to do is upload a file.
// There doesn't seem to be another way to check if the file exists
// using just the ssh2 resource without using the ssh2.sftp stream wrapper.
// If you want to check if the file exists use ssh2_sftp_stat() it will
// return false if the file does not exist.
$file2 = 'test.txt';

$res = ssh2_scp_send($connection, $localFile, $file2);
if($res) {
     print 'Sent file ' . $file . PHP_EOL;
} else {
     print 'There was an error copying file to remote.' . PHP_EOL;
}

/*
// List contents of remote directory
$i = new \RecursiveDirectoryIterator($path, 
\RecursiveDirectoryIterator::SKIP_DOTS);

while($i->valid()) {
     print $i->getPathname();
     if($i->isDir()) {
         print $i->getPath() . PHP_EOL;
     } else {
         print $i->getFilename() . PHP_EOL;
     }
     $i->next();
}
*/


// shutdown
unset($sftp); // If you don't unset $sftp ssh2_disconnect will throw a 
segfault.
ssh2_disconnect($connection);

function GetConfigArr($file)
	{
	global $pagesDir;
	$configStr=@file_get_contents($file);
	if ($configStr===false)
		exit("*** HMAC: Config file '$file' is missing from $pagesDir; please 
read ".
			"file HMAC\Installation.txt for the steps to set up your HMAC website.");
	return json_decode($configStr,true);
	} // GetConfigArr
?>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.