You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SFTP上传文件出现0字节错误,结合PHP代码寻求解决方案

SFTP上传文件出现0字节错误的排查与解决办法

我之前也碰到过一模一样的问题,结合你给出的代码片段,咱们一步步拆解可能的原因和对应的解决办法:

1. 核心问题:没正确读取本地上传的文件内容

你的代码里只拿到了上传文件的原始文件名$filename,但完全没处理PHP上传文件的临时存储路径。PHP会把上传的文件先存在服务器临时目录,路径存在$_FILES["fileToUpload"]["tmp_name"]里——如果直接创建远程文件但不把临时文件的内容写进去,远程文件自然就是0字节。

解决代码示例

<?php 
if(isset($_POST["submit"])) { 
    $filename = $_FILES["fileToUpload"]["name"];
    $localTmpFile = $_FILES["fileToUpload"]["tmp_name"]; // 关键:获取本地临时文件路径
    
    require_once('/home/Script_Server/login_server_ftp.php'); 
    $resConnection = ssh2_connect($strServer, $strServerPort); 

    if(ssh2_auth_password($resConnection, $strServerUsername, $strServerPassword)){ 
        echo "connected"; 
        $resSFTP = ssh2_sftp($resConnection); 

        // 拼接远程文件完整路径
        $remoteFilePath = "ssh2.sftp://{$resSFTP}/var/www/html/mysite.com/folder/" . $filename;
        $remoteFileHandle = fopen($remoteFilePath, 'w');
        
        // 读取本地临时文件内容并写入远程
        if ($remoteFileHandle) {
            fwrite($remoteFileHandle, file_get_contents($localTmpFile));
            fflush($remoteFileHandle); // 强制刷新缓冲区
            fclose($remoteFileHandle);
            echo "文件上传成功";
        } else {
            echo "无法打开远程文件";
        }
        
        ssh2_disconnect($resConnection);
    } else {
        echo "SFTP认证失败";
    }
}

2. 远程目录权限不足

如果远程目录/var/www/html/mysite.com/folder/没有给SFTP用户写入权限,系统可能允许你创建空文件,但无法写入内容,最终就是0字节。

排查与解决

  • 登录目标服务器,用ls -l /var/www/html/mysite.com/查看目录权限,确保SFTP所属的用户/用户组有w(写入)权限。
  • 可以先在代码里加个权限测试:
$testFile = "ssh2.sftp://{$resSFTP}/var/www/html/mysite.com/folder/test_perm.txt";
$testHandle = fopen($testFile, 'w');
if ($testHandle) {
    fwrite($testHandle, "权限测试内容");
    fclose($testHandle);
    echo "目录权限正常";
    unlink($testFile); // 测试完删除文件
} else {
    echo "远程目录无写入权限,请调整权限";
}

3. SSH2扩展缓冲区未刷新

有时候ssh2的fwrite不会立即把内容写入远程服务器,程序提前断开连接后,缓冲区的内容丢失,导致文件为空。

解决办法
fwrite之后调用fflush($remoteFileHandle)强制刷新缓冲区,再关闭文件句柄,最后断开SFTP连接(就像上面代码示例里那样)。

4. 大文件导致内存不足或超时

如果上传的文件很大,用file_get_contents一次性读取整个文件会占用大量内存,可能导致读取失败,进而写入空内容。

解决办法:分块读写
用循环分块读取本地文件,再写入远程,避免内存溢出:

$localHandle = fopen($localTmpFile, 'rb');
$remoteHandle = fopen($remoteFilePath, 'wb');

// 每次读取8KB分块写入
while (!feof($localHandle)) {
    fwrite($remoteHandle, fread($localHandle, 8192));
}

fclose($localHandle);
fclose($remoteHandle);

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

火山引擎 最新活动