如何在sftp服务器上用curl上传文件


How to upload file with curl on sftp server

此代码

$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;

给我这个错误:

文件上载错误。7(无法将文件写入磁盘)

我的要求很简单,我只需要使用curl在实时服务器上上传text.txt文件。

因此,对于诊断SSH/SFTP问题,我认为phpseclib,一个纯PHP SFTP实现,是最好的方法。方法如下:

<?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();
?>

特别是,phpseclib的有用之处在于它能够创建日志文件,这样您就可以看到发生了什么

我认为它也更容易使用,哈哈,但这取决于你。

这个问题的答案今天对我有所帮助。

我只想指出,'sftp://$user:$pass@myserver.com/upload/$filename'中的变量永远不会被解释,因为您使用的是单引号。您应该使用双引号或将变量连接到单引号字符串。

也许这个链接可以帮助你,

有一些使用CURL上传文件的不同方法的例子。

或者试试这个

$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.';
}

我还遇到了一个问题,即我用作起点的脚本无法工作。所以我只设置了CURLOPT_VERBOSE,并将curl_error结果添加到输出中。通过这种方式,我意识到curl在我的情况下没有启用ssh支持,我可以通过使用ssh支持重新出现(=在其他系统上重新构建,我在gentoo上)来解决这个问题。此外,代码中的单引号会阻止正确的变量替换。在解决了这些问题和一些拼写错误后,我使用您的功能,使用我的测试证书和主机,得到的结果现在看起来是这样的:

  • 正在尝试
  • TCP_NODELAY集合
  • 连接到()端口22(#0)
  • SSH MD5指纹:4dbea14faf74ee128d5874017332f4ef
  • 可用的SSH身份验证方法:公钥、键盘交互
  • 使用SSH私钥文件"/root/.SSH/id_rsa"
  • SSH公钥身份验证失败:用户名/PublicKey组合无效
  • 连接到代理失败
  • 已初始化键盘交互式身份验证
  • 身份验证完成
  • 我们完全上传了
  • 与主机的连接#0保持不变
  • 正在关闭连接0

文件上传成功。0

我不知道你的代码是否工作过,但我用了你的一些代码来让我的代码工作

我发现我需要使用CURLOPT_USERPWD并将用户和密码从url中删除。但在我寻找答案的过程中,我也发现有人需要做相反的事情,去掉CURLOPT_USERPWD,并将它们放在url中。这可能与服务器有关

如果我在你的帖子中,我会添加curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
然后,当我让它工作时,如果你觉得绝对需要指纹,我会把它取下来
最后4个curl_setopt仅用于故障排除。

此代码已在两个不同的SFTP服务器上进行了测试
一个是GoDaddy VPS,一个是CentOS 7盒子,另一个是GoAnywhere服务器。

$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);