我试图列出远程SFTP服务器中某个目录中的所有文件作为下载链接,以便用户可以选择下载这些文件。到目前为止,我已经能够读取并列出特定目录中的所有文件作为下载链接,但是当我尝试通过右键单击并选择“另存为”来实际下载文件时,出现“失败-没有文件” “ 信息。 Picture of my results
<?php
$connection = ssh2_connect('url', 22);
ssh2_auth_password($connection, username, password);
$sftp = ssh2_sftp($connection);
$sftp_fd = intval($sftp);
if ($handle = opendir("ssh2.sftp://$sftp_fd/path/to/remote/dir/")) {
while (($entry = readdir($handle)) !== false) {
if ($entry == "." || $entry == "..") { continue; }
echo '<a href="/path/to/remote/dir/' .$entry. '">' .$entry. '<br>'.'</a>';
}
closedir($handle);
}
?>
答案 0 :(得分:0)
您在生成的<a>
标记中的链接指向不包含链接文件的Web服务器。
您需要做的是链接到PHP脚本,并为其指定要下载的文件的名称。然后,该脚本将从SFTP服务器下载文件,并将下载的文件传回用户(至Web浏览器)。
echo '<a href="download.php?file='.urlencode($entry).'">'.htmlspecialchars($entry).'</a>';
download.php
脚本的非常简单的版本:
<?
header('Content-Type: application/octet-stream');
$connection = ssh2_connect('url', 22);
ssh2_auth_password($connection, username, password);
$sftp = ssh2_sftp($connection);
$sftp_fd = intval($sftp);
echo file_get_contents("ssh2.sftp://$sftp_fd/path/to/remote/dir/" . $_GET["file"]);
尽管对于一个真正正确的解决方案,您应该提供一些与文件相关的HTTP标头,例如Content-Length
,Content-Type
和Content-Disposition
。
上述琐碎的示例也将首先将整个文件从SFTP服务器下载到Web服务器。只有这样,它才会开始将其流式传输给用户(Web浏览器)。这是浪费时间,也浪费了Web服务器上的内存(如果文件足够大)。
看到类似的问题(虽然是FTP,而不是SFTP):
Download file via PHP script from FTP server to browser with Content-Length header without storing the file on the web server
您可能还想自动检测Content-Type
,除非您的所有文件都属于同一类型。
您当然可以使用URL rewrite来使网址更漂亮。
即将download.php?file=myfile.txt
改成download/myfile.txt
。