此代码
$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);