duanmajing9332 2013-02-25 14:44
浏览 8
已采纳

在PHP中比较服务器上的大文件大小和post请求中的大小

I have an Apache server where files are uploaded in an HTTP post request (<form enctype="multipart/form-data" action="upload.php" method="post">). It happens from time to time (very rarely, but it happens nonetheless), for reasons that still elude me, that after a file has been uploaded, its size on disk will not match the size of the original file.

What I'd like to do is to catch those errors before returning from the PHP script which copies the file from /tmp to its final destination. My first idea was to compare $_FILES['uploadedfile']['size'] and filesize($target_path), which seems to work fine for files up to 2GB. However, as soon as the file size's number of bytes is over 32 bits long, $_FILES['uploadedfile']['size'] overflows and becomes negative. Moreover, I suspect that using this value as the "reference file size" might be too late in the upload process (i.e. it's the file size on the server, not on the client).

There's the possibility of extracting the file size from $_SERVER['CONTENT_LENGTH'], but this value also includes what seems to be request "metadata", and I could not find documentation on how to separate that data from the actual file size (the "metadata" size changes from request to request)

The easiest way would be to ask the client to post the source's file size as a request parameter, but I'd like to have as little change as possible on the client's side.

I was also told an "HTTP PUT" could prevent the problem in the first place, but I'm still in the early stages of investigating that. I'd still like to find a solution with my current POST method.

For reference, my upload script looks approximately like this now:

$id = strtolower($_POST["assetid"]);
$project = strtolower($_POST["project"]);
$target_path = Settings::getAssetPath($project,$id);

if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
    if (filesize($target_path) != $_FILES['uploadedfile']['size']){
        header("HTTP/1.0 500 Internal Server Error");
        $result .= "Uploaded file size does not match source file size!<br />";
    }
    else {
        header("HTTP/1.0 200 OK");
        $result .= "The file " . basename($_FILES['uploadedfile']['name']) . " has been uploaded successfully.";
    }
} else {
    header("HTTP/1.0 500 Internal Server Error");
    $result .= "There was an error uploading the file, please try again!<br />";
}

Any ideas are very welcome!

  • 写回答

1条回答 默认 最新

  • douyan8070 2013-02-25 14:48
    关注

    Your upload script is incorrect. ['size'] is what has been received by the server. If the upload aborts/fails for any reason, ['size'] WILL be incorrect. You must check for upload success before doing ANYTHING with the upload data:

    if($_FILES['uploadedfile']['error'] !== UPLOAD_ERR_OK) {
       die("Upload failed with error code " . $_FILES['uploadedfile']['error']);
    }
    

    the error codes are defined here: http://www.php.net/manual/en/features.file-upload.errors.php

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看