1

This code

$user = 'user';
$pass = 'password';
$filename = 'text.txt';
error_reporting(E_ALL);
ini_set('display_errors', 1);
$ch = curl_init();
$localfile = 'text.txt';
$fp = fopen($localfile, 'r');
curl_setopt($ch, CURLOPT_URL, 'sftp://$user:$pass@myserver.com/upload/$filename');
curl_setopt($ch, CURLOPT_UPLOAD, 1);
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_SFTP);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localfile));
curl_exec ($ch);
$error_no = curl_errno($ch);
curl_close ($ch);
if ($error_no == 0) {
        $error = 'File uploaded succesfully.';
} else {
        $error = 'File upload error.';
}
echo $error.' '.$error_no;

gives me this error:

File upload error. 7 ( Failed to write file to disk )

My requirement is simple, I just need to upload text.txt file on live server using curl.

Cristian Ciupitu
  • 20,270
  • 7
  • 50
  • 76
J.Rob
  • 436
  • 1
  • 5
  • 22
  • Well, are you able to upload the file from the same server using the same credentials with the command line sftp utility? Because this looks like a server issue... – arkascha Aug 12 '13 at 06:15
  • Have you tried using `CURLOPT_VERBOSE => 1`? – Ja͢ck Aug 12 '13 at 07:00
  • There are a lot of answers here, but I don't see a solution using ssh2 or cURL sFTP, an encrypted or unencrypted private key, and a solution that is tested and that works. It seems that no one who has accomplished a file upload in sFTP in PHP code has shared their code. Even the PHP Manual seems to have no working example that uploads a file securely. – David Spector Jan 17 '21 at 18:44

5 Answers5

2

So for diagnosing SSH / SFTP problems I think phpseclib, a pure PHP SFTP implementation, is the best approach. Here's how:

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

define('NET_SFTP_LOGGING', NET_SFTP_LOG_COMPLEX);

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

$sftp->put('text.txt', 'text.txt', NET_SFTP_LOCAL_FILE);

echo $sftp->getSFTPLog();
?>

In particular, what's useful about phpseclib is it's ability to create log files so you can see what's going on.

I think it's easier to use, too, lol, but that's up to you.

neubert
  • 15,947
  • 24
  • 120
  • 212
  • any suggestions on how to install and use phpseclib. Ive tried multiple ways and cannot get it to function correctly – Beanno1116 Jun 15 '22 at 17:32
  • @Beanno1116 - you should post that as a new question. Use phpseclib, composer and php as the tags – neubert Jun 15 '22 at 18:31
1

Maybe this link can help you,

There are some examples of different ways to upload files using CURL.

or try this

$localfile = 'sample.txt';
$user      = 'user';
$password  = 'pass';
$host      = 'ftp.remote.com';

$ch = curl_init();
$fp = fopen($localfile, 'r');

curl_setopt($ch, CURLOPT_URL, "sftp://{$user}:{$password}@{$host}/{$localfile}");
curl_setopt($ch, CURLOPT_UPLOAD, 1);
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_SFTP);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localfile));
curl_exec ($ch);

$error_no = curl_errno($ch);
curl_close ($ch);

if ($error_no == 0) {
    $error = 'File uploaded succesfully.';
} else {
    $error = 'File upload error.';
}
muhkuh2005
  • 57
  • 6
Padmanathan J
  • 4,614
  • 5
  • 37
  • 75
1

Answers to this question helped me today.

I just want to point out that your vars in 'sftp://$user:$pass@myserver.com/upload/$filename' will never get interpreted since you're using single quotes. You should either use double quotes or concatenate your vars to single quoted strings.

Gadzy
  • 11
  • 1
0

I also had the problem that your script, that I used as starting point, didn`t work. So I just set the CURLOPT_VERBOSE and added curl_error result to the output. This way, I realized, that curl had no ssh support enabled in my case, which I could solve by re-emerging (=re-building on other systems, I am on gentoo) with ssh support. Also the single-quotes in your code prevent correct variable substitution. After solving those problems, and few typos, my result with your function, using my test-credentials and host, looks like this now :

  • Trying ...
  • TCP_NODELAY set
  • Connected to () port 22 (#0)
  • SSH MD5 fingerprint: 4dbea14faf74ee128d5874017332f4ef
  • SSH authentication methods available: publickey,keyboard-interactive
  • Using SSH private key file '/root/.ssh/id_rsa'
  • SSH public key authentication failed: Username/PublicKey combination invalid
  • Failure connecting to agent
  • Initialized keyboard interactive authentication
  • Authentication complete
  • We are completely uploaded and fine
  • Connection #0 to host left intact
  • Closing connection 0

File uploaded successfully. 0

Oliver
  • 105
  • 13
0

I do not know if you ever got yours working but I used some of your code to get mine working.

I found I needed to use CURLOPT_USERPWD and take user and password out of the url. But in my search for an answer I also found someone that need to do the opposite, get rid of the CURLOPT_USERPWD, and put them in the url. That may be server dependent.

If I were at the point of your post I would add the curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);.
Then when I got it working I would remove it if you feel an absolute need for the finger print.
The last 4 curl_setopt's are only for trouble shooting.

This code has been tested on two different SFTP servers.
Once is a GoDaddy VPS, CentOS 7 box, the other a GoAnywhere server.

$host = 'xx.xxx.xxx.xxx/server/public_html';
$username = 'username';
$password = 'password';
$localfile = "/home/server/public_html/xxx/resultTest.txt";
$fp = fopen($localfile, 'r');
$url = "sftp://@$host";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_SFTP);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localfile));
curl_setopt($ch, CURLOPT_UPLOAD, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_TIMEOUT,2);
curl_setopt($ch, CURLOPT_FAILONERROR,true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
$response = curl_exec($ch); 
$error = curl_error($ch);
curl_close($ch);
Misunderstood
  • 5,534
  • 1
  • 18
  • 25