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

PHP CLI实现SFTP文件夹批量文件上传技术求助

嘿,很高兴能帮到你!既然你已经能搞定单个文件的SFTP上传,那扩展到批量上传文件夹里的所有文件其实没那么难~ 下面我给你一步步拆解实现方案:

实现PHP SFTP批量上传文件夹文件

首先给你一个基础的批量上传脚本,能处理文件夹里的所有一级文件,之后我再补充递归上传子文件夹的扩展方案:

<?php
// 假设你已经成功建立SFTP连接,$sftp 是你的ssh2_sftp资源对象
$localFolder = "C:/你的本地文件夹路径/"; // 比如 "C:/temp/upload_files/"
$remoteFolder = "/远程服务器目标文件夹/"; // 比如 "/data/user_uploads/"

// 先确保远程目标文件夹存在,不存在就创建(支持多级目录)
if (!file_exists("ssh2.sftp://$sftp$remoteFolder")) {
    mkdir("ssh2.sftp://$sftp$remoteFolder", 0755, true);
}

// 遍历本地文件夹下的所有条目
$files = scandir($localFolder);
foreach ($files as $file) {
    // 跳过系统默认的当前目录(.)和上级目录(..)
    if ($file === '.' || $file === '..') {
        continue;
    }

    $localFile = $localFolder . $file;
    // 只处理文件,暂时跳过子文件夹(需要处理子文件夹看后面的扩展)
    if (is_file($localFile)) {
        $remoteFile = $remoteFolder . $file;

        // 复用你原来的上传逻辑,加上错误处理更稳妥
        try {
            $ostream = fopen("ssh2.sftp://$sftp$remoteFile", 'w');
            if (!$ostream) {
                throw new Exception("无法打开远程文件: $remoteFile");
            }

            $ofile = file_get_contents($localFile);
            if ($ofile === false) {
                throw new Exception("无法读取本地文件: $localFile");
            }

            $writeResult = fwrite($ostream, $ofile);
            if ($writeResult === false) {
                throw new Exception("写入远程文件失败: $remoteFile");
            }

            echo "✅ 成功上传: $localFile -> $remoteFile\n";
            fclose($ostream);
        } catch (Exception $e) {
            echo "❌ 上传失败: " . $e->getMessage() . "\n";
        }
    }
}
?>

关键部分说明

  • 遍历本地文件:用scandir获取文件夹内所有条目,跳过.和..避免无效循环
  • 远程目录检查:上传前先确认远程文件夹存在,不存在则自动创建,避免因目录不存在导致上传失败
  • 错误处理:加入try-catch和状态判断,能快速定位问题(比如文件权限不足、网络中断等)

扩展:递归上传子文件夹

如果需要连子文件夹一起完整上传,可以用递归函数实现:

<?php
function uploadDirectoryRecursively($sftp, $localDir, $remoteDir) {
    // 创建当前层级的远程目录
    if (!file_exists("ssh2.sftp://$sftp$remoteDir")) {
        mkdir("ssh2.sftp://$sftp$remoteDir", 0755, true);
    }

    $files = scandir($localDir);
    foreach ($files as $file) {
        if ($file === '.' || $file === '..') {
            continue;
        }

        $localPath = $localDir . DIRECTORY_SEPARATOR . $file;
        $remotePath = $remoteDir . '/' . $file; // SFTP统一用/作为路径分隔符

        if (is_dir($localPath)) {
            // 如果是子文件夹,递归调用自身处理
            uploadDirectoryRecursively($sftp, $localPath, $remotePath);
        } elseif (is_file($localPath)) {
            // 执行文件上传逻辑
            try {
                $ostream = fopen("ssh2.sftp://$sftp$remotePath", 'w');
                if (!$ostream) {
                    throw new Exception("无法打开远程文件: $remotePath");
                }

                $ofile = file_get_contents($localPath);
                if ($ofile === false) {
                    throw new Exception("无法读取本地文件: $localPath");
                }

                fwrite($ostream, $ofile);
                echo "✅ 成功上传: $localPath -> $remotePath\n";
                fclose($ostream);
            } catch (Exception $e) {
                echo "❌ 上传失败: " . $e->getMessage() . "\n";
            }
        }
    }
}

// 调用示例
$localFolder = "C:/temp/upload_files/";
$remoteFolder = "/data/user_uploads/";
// 确保$sfpt是已经成功建立的SFTP连接资源
uploadDirectoryRecursively($sftp, $localFolder, $remoteFolder);
?>

注意事项

  • 确保你的PHP已经启用了ssh2扩展,否则所有SFTP相关函数都无法使用
  • Windows本地路径可以用/或者转义的\\,推荐用DIRECTORY_SEPARATOR适配系统
  • 远程服务器目标文件夹要确保有写入权限,本地文件也要有读取权限

内容的提问来源于stack exchange,提问作者MdM

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:03:17