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
相关产品推荐
相关产品推荐

