使用 SFTP 上传文件

Posted

技术标签:

【中文标题】使用 SFTP 上传文件【英文标题】:Uploading files with SFTP 【发布时间】:2012-03-23 06:13:29 【问题描述】:

我已成功通过 ftp 上传文件,但我现在需要通过 SFTP 上传。我可以成功连接到远程服务器,创建一个文件并写入它,但是我无法将现有文件从本地服务器上传到远程服务器。 ftp_put 是否没有通过 sftp 连接触发?

我用来写文件的代码:

//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";

有没有人成功抓取本地文件并通过上述方法使用 sftp 上传?一个例子将不胜感激。

谢谢

【问题讨论】:

你为什么叫它resFile?为什么是“res”?它代表什么? 我猜的结果.. @Black 你在哪里使用 $strServerPassword 在你的 src 中?我看不到它在这里被使用。 【参考方案1】:

上面的方法(涉及sftp)可以使用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);

您也可以尝试使用ssh2_scp_send

【讨论】:

效果很好,谢谢。我会为未来的项目添加书签! 这很棒,但不要忘记为用户禁用打开的基本目录。【参考方案2】:

就个人而言,我更喜欢避免使用 PECL SSH2 扩展。我的首选方法涉及phpseclib, a pure PHP SFTP implementation。这是 phpseclib 2.0 的示例(需要 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);
?>

这是 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);
?>

我喜欢 phpseclib 而不是 PECL 扩展的一大优点是它是可移植的。也许 PECL 扩展适用于一个版本的 Linux,但不适用于另一个版本。在共享主机上,它几乎从不工作,因为它几乎从未安装过。

令人惊讶的是,phpseclib 也是faster。如果您需要确认上传的文件,您可以使用 phpseclib 的内置日志记录作为证明。

【讨论】:

我正在使用上面的脚本上传一些 csv 文件,但我收到以下错误:Net\SSH2.php 中第 3521 行的最大执行时间超过 120 秒,我该如何超过它。 【参考方案3】:

对我来说这很有效:

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

不过,我必须先安装 libssh2-php:

sudo apt-get install libssh2-php

【讨论】:

我得到包 libssh2-php 不可用,所以请改用sudo apt-get install php-ssh2【参考方案4】:

对于phpseclib 的简单文档,一个纯PHP SFTP 实现

参考以下链接:

Uploading files over SFTP using PHP

文件夹结构:

Main Folder->
    my-files(Contain File Which Transfer To Remote Server)
    phpseclib0.3.0
    sftp.php

【讨论】:

【参考方案5】:

分享进一步的输入,当将文件从 Linux(64 位)复制到 Windows(32 位)时,发现 ssh2_scp_send 没有正确复制(字节不同),sftp 例程运行良好。当使用带有 stfp 的 Windows 时,如果 Cygwin 在 Windows 机器上用于 SSH,则需要将 C:\to\path 的路径设置为 ssh2.sftp://$resSFTP/cygdrive/c/to/path .

【讨论】:

以上是关于使用 SFTP 上传文件的主要内容,如果未能解决你的问题,请参考以下文章

使用 python 上传 SFTP 文件

使用 ppk 文件上传 Paramiko sftp [重复]

使用 PowerShell 将文件上传到 SFTP

使用 python 通过 sftp 上传文件

java向SFTP服务器上传文件,如何判断服务器上的文件夹是不是存在?

用JSch实现SFTP文件上传