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 ?>