PHP文件上传PUT请求改变文件,而POST不改变

时间:2014-07-15 17:50:01

标签: php apache

我有以下代码,只是为了从PUT请求或POST请求中获取文件并将其复制到服务器。

if ($_SERVER['REQUEST_METHOD']=='PUT') {

    $putdata = fopen("php://input","r");
    $fp = fopen("myputfile.ext","w");

    while ($data = fread($putdata, 1024))
            fwrite($fp, $data);

    fclose($fp);
    fclose($putdata);

} else {
    move_uploaded_file($_FILES['package']['tmp_name'], "mypostfile.ext");
}

因此对于POST请求,文件(在这种情况下是一个zip文件)保持不变。使用PUT请求,文件会被更改。

[root@vm-centos6-010 put]# diff myputfile.ext ../post/mypostfile.ext 
Binary files myputfile.ext and ../post/mypostfile.ext differ

这是一个zip文件,根据unzip,在开头添加了额外的165个字节。它仍然成功解压缩,但POST文件不会出现警告消息。我真正拥有的唯一其他线索是文件大小相差211个字节。

我已经通过php文档和十几个帖子进行了梳理,但我无法弄清楚为什么这两种方法会有所不同。

有什么见解?

感谢。

2 个答案:

答案 0 :(得分:1)

听起来有些东西被添加到输出中。在文本编辑器中打开ZIP文件,检查内容,查看服务器/ PHP生成的警告消息/无意输出。

答案 1 :(得分:1)

^M是窗口行结束字符CR LF0x0D 0x0A\r\n)。

打开流$putdata = fopen("php://input","r");

首先发送标题,然后发送文件(标题和正文由\r\n\r\n分配)。

我不知道您的设置的哪个部分导致了错误,但是您应该检查这些字符是否存在,您知道该文件是在\r\n\r\n之后开始的。

您的请求中有错误。你试图提出请求的方式是错误的。

How to receive a file via HTTP PUT with PHP

<强> PUT

  

这直接补充了GET。 GET请求表明的地方   服务器应该在指定的位置返回文档   请求URI在响应体中,PUT方法表示   服务器应将数据存储在该位置的请求正文中   由请求URI指定。

这意味着,您可能没有单个PUT请求中的多部分请求。 必须有一个内容类型。 (多部分表示为:------WebKitFormBoundaryhPjNpS0gBhbCC8aR

在POST请求中,允许多部分(想到:enctype='multipart/form-data')。

带文件的put请求不得包含任何其他内容。意思是,如果你想把文件+变量放在一起,那么变量需要附加到URI中,但不能像在POST中那样在体内。

更新可能的解决方法(我知道这是一个肮脏的解决方案,请不要责怪我......):

while ($data = fread($putdata, 1024)) {
    if (strpos($data, '\r\n\r\n') !== false) {
        $data = explode("\r\n\r\n", $data);  // seperate multipart header from body
        $data = $data[1];                    // assign body to $data
    } elseif(strpos($data, '\r\n-' !== false) {
        $data = explode("\r\n-", $data);  // seperate footer from body
        $data = $data[0];                    // assign body to $data
    }

    fwrite($fp, $data);
}