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 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)
  • ¥15 AIC3204的示例代码有吗,想用AIC3204测量血氧,找不到相关的代码。