Re: Hoping for a working example of SFTP in PHP

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

No problem.

The $remoteDir variable should be in the format 
'%s/path/to/the/files/directory', sprintf will replace the %s with the 
$streamUrl.

You could also just use  $streamUrl . '/path/to/the/files/directory'; as 
well.
If you only want to copy one single file, you can also use $streamUrl . 
'/path/to/the/file';  If this is the case, and you don't care if the 
file exists, I would suggest that you just use the ssh2_scp_send 
function instead of streams.

1) I put two different ways of copying files.  If you are using the 
stream "ssh2.sftp://" copy just works on the stream.  If you want to 
avoid the $streamUrl stuff you can also just use the function ssh2_scp_send

ssh2_scp_send($connection, 'local-file', 'full-path-to-remote-file');

2) This works without a user password.  The passphrase is used to 
decrypt the key if it is encrypted.  Usually on shared hosts they 
require a passphrase when you create the ssh key.  I'm not sure what 
your situation is.  If you have control of the creation of keys, when 
you create one and just hit enter when it asks for a passphrase.

Eric

On 2/2/21 1:40 PM, David Spector wrote:

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