Re: Hoping for a working example of SFTP in PHP
| From: | David Spector | Date: | Tue, 02 Feb 2021 21:40:36 +0000 |
| Subject: | Re: Hoping for a working example of SFTP in PHP | ||
| References: | 1 2 3 4 5 6 7 8 9 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-327453@lists.php.net to get a copy of this message | ||
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 sikofitt@gmail.com
// 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
?>