You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 5.6中如何从SFTP下载目录下所有文件

解决Laravel中SFTP文件下载到本地public/InputFiles的问题

嗨,作为Laravel新手能搞定SFTP目录列表已经超棒啦!咱们一步步来解决把文件保存到本地public/InputFiles的问题~

第一步:确认文件系统配置

首先得确保config/filesystem.php里的磁盘配置没问题,尤其是SFTP和本地目标目录的配置。建议新增一个专门指向public/InputFiles的磁盘,方便后续操作:

// config/filesystem.php
'disks' => [
    // 原有local配置(默认指向storage/app)
    'local' => [
        'driver' => 'local',
        'root' => storage_path('app'),
    ],
    // 你的SFTP配置(确保信息正确)
    'sftp' => [
        'driver' => 'sftp',
        'host' => '你的SFTP主机地址',
        'username' => 'SFTP用户名',
        'password' => 'SFTP登录密码', // 也可以用私钥,注释掉密码换成下面一行
        // 'privateKey' => storage_path('app/sftp/id_rsa'),
        'port' => 22,
        'root' => '/SFTP上的目标目录路径', // 比如你要访问的SFTP目录是/data/files,就填这个
        'timeout' => 30,
    ],
    // 新增指向public/InputFiles的磁盘
    'input_files' => [
        'driver' => 'local',
        'root' => public_path('InputFiles'),
        'visibility' => 'public',
    ],
],

第二步:实现文件下载的代码

这里给你三种可靠的实现方式,选一种适合你的情况:

方式一:跨磁盘直接复制(简单高效)

如果你的Laravel版本支持跨磁盘复制(Laravel 5.5+基本都支持),可以直接用copy方法:

use Illuminate\Support\Facades\Storage;

// 获取SFTP目录下的所有文件
$sftpFiles = Storage::disk('sftp')->files();

foreach ($sftpFiles as $file) {
    // 先检查文件是否存在,避免无效操作
    if (Storage::disk('sftp')->exists($file)) {
        // 从SFTP复制到本地input_files磁盘(对应public/InputFiles)
        $isSuccess = Storage::disk('sftp')->copy(
            $file,
            Storage::disk('input_files')->path(basename($file))
        );

        // 输出结果(实际项目可以换成日志记录)
        echo $isSuccess ? "文件「".basename($file)."」保存成功!<br>" : "文件「".basename($file)."」保存失败!<br>";
    }
}

方式二:读取内容后写入(兼容更多场景)

如果跨磁盘复制不生效,或者需要对文件内容做处理,可以先读取SFTP文件内容,再写入本地:

use Illuminate\Support\Facades\Storage;

$sftpFiles = Storage::disk('sftp')->files();

foreach ($sftpFiles as $file) {
    if (Storage::disk('sftp')->exists($file)) {
        // 读取SFTP文件内容
        $fileContent = Storage::disk('sftp')->get($file);
        // 写入到public/InputFiles目录
        Storage::disk('input_files')->put(basename($file), $fileContent);

        // 验证写入结果
        $isExist = Storage::disk('input_files')->exists(basename($file));
        echo $isExist ? "文件「".basename($file)."」保存成功!<br>" : "文件「".basename($file)."」保存失败!<br>";
    }
}

方式三:大文件用流处理(避免内存溢出)

如果要下载的是大文件,上面两种方法可能会占用过多内存,这时候用流的方式更稳妥:

use Illuminate\Support\Facades\Storage;

$sftpFiles = Storage::disk('sftp')->files();

foreach ($sftpFiles as $file) {
    if (Storage::disk('sftp')->exists($file)) {
        // 打开SFTP文件的读流
        $readStream = Storage::disk('sftp')->readStream($file);
        // 写入本地文件的写流
        Storage::disk('input_files')->writeStream(basename($file), $readStream);
        // 关闭流,释放资源
        fclose($readStream);

        echo "文件「".basename($file)."」已通过流方式保存!<br>";
    }
}

第三步:排查常见问题

如果还是失败,大概率是这几个原因:

  • 权限不足:确保public/InputFiles目录有写入权限。Linux服务器可以执行命令:
    chmod -R 755 public/InputFiles
    # 或者根据服务器运行用户调整所属组
    chown -R www-data:www-data public/InputFiles
    
  • SFTP路径错误:检查config/filesystem.php中sftp的root配置是否正确,比如你要访问的SFTP文件实际在/home/user/files,就不能填成/home/user,否则files()获取的路径会不对。
  • Laravel版本兼容:如果是非常老的Laravel版本(比如5.4及以下),跨磁盘复制功能可能不完善,建议用方式二或方式三。

内容的提问来源于stack exchange,提问作者umair.ashfr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:04:07