5Answers

I have successfully uploaded files over ftp, but I now need to do via SFTP. I can successfully connect to the remote server, create a file and write to it, but I am unable to upload an existing file from my local server to the remote server. Is ftp_put not firing with an sftp connection?

My code used to write a file :

//Send file via sftp to server

$strServer = "*****";
$strServerPort = "****";
$strServerUsername = "*****";
$strServerPassword = "*****";
$csv_filename = "Test_File.csv";

//connect to server
$resConnection = ssh2_connect($strServer, $strServerPort);

if(ssh2_auth_password($resConnection, $strServerUsername, $strServerPassword)){
    //Initialize SFTP subsystem

    echo "connected";
    $resSFTP = ssh2_sftp($resConnection);    

    $resFile = fopen("ssh2.sftp://{$resSFTP}/".$csv_filename, 'w');
    fwrite($resFile, "Testing");
    fclose($resFile);                   

}else{
    echo "Unable to authenticate on server";
}

Has anyone had any success in grabbing a local file and uploading via a method such as above with sftp? An example would be greatly appreciated.

Thanks

Answer

With the method above (involving sftp) you can use stream_copy_to_stream:

$resFile = fopen("ssh2.sftp://{$resSFTP}/".$csv_filename, 'w');
$srcFile = fopen("/home/myusername/".$csv_filename, 'r');
$writtenBytes = stream_copy_to_stream($srcFile, $resFile);
fclose($resFile);
fclose($srcFile);

You can also try using ssh2_scp_send

  • 46
Reply Report

Personally, I prefer avoiding the PECL SSH2 extension. My preferred approach involves phpseclib, a pure PHP SFTP implementation. Here's an example with phpseclib 2.0 (requires composer):

<?php
require __DIR__ . '/vendor/autoload.php';

use phpseclib\Net\SFTP;

$sftp = new SFTP('www.domain.tld');
if (!$sftp->login('username', 'password')) {
    exit('Login Failed');
}

$sftp->put('remote.ext', 'local.ext', SFTP::SOURCE_LOCAL_FILE);
?>

Here's that same example with phpseclib 1.0:

<?php
include('Net/SFTP.php');

$sftp = new Net_SFTP('www.domain.tld');
if (!$sftp->login('username', 'password')) {
    exit('Login Failed');
}

$sftp->put('remote.ext', 'local.ext', NET_SFTP_LOCAL_FILE);
?>

One of the big things I like about phpseclib over the PECL extension is that it's portable. Maybe the PECL extension works on one version of Linux but not another. And on shared hosts it almost never works because it's hardly ever installed.

phpseclib is also, surprisingly, faster. And if you need confirmation that the file uploaded you can use phpseclib's built-in logging as proof.

  • 27
Reply Report
      • 2
    • I am uploading some csv files using the script above but i am getting the following error: Maximum execution time of 120 seconds exceeded in NetSSH2.php on line 3521, how can i exceed it.

For me this worked:

$connection = ssh2_connect($server, $serverPort);

if(ssh2_auth_password($connection, $serverUser, $serverPassword)){
    echo "connected\n";
    ssh2_scp_send($connection, "/path/to/local/".$file, "/path/to/remote/".$file);
    echo "done\n";
} else {
    echo "connection failed\n";
}

I had to install libssh2-php first, though:

sudo apt-get install libssh2-php
  • 14
Reply Report

Sharing further inputs, found ssh2_scp_send was not copying properly (bytes were different) when the copying the file from Linux (64 bit) to Windows (32 bit) , there sftp routine worked perfectly. When using Windows with stfp, the path in case of C:\to\path needs to be put as ssh2.sftp://{$resSFTP}/cygdrive/c/to/path if Cygwin is used for SSH on the Windows box.

  • 1
Reply Report

Warm tip !!!

This article is reproduced from Stack Exchange / Stack Overflow, please click

Trending Tags

Related Questions