我有以下代码,只是为了从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'ed文件中没有出现警告消息。我真正知道的唯一线索是文件大小相差211字节。
我已经梳理了php文档和十几篇文章,但我不明白为什么这两种方法会不同。
见解吗?
谢谢。
^M
为windows行结束字符CR LF
(0x0D 0x0A
或'r'n
)。
打开流$putdata = fopen("php://input","r");
首先发送报头,然后发送文件(报头和正文由'r'n'r'n
分隔)。
我不知道你的设置是哪个部分导致错误,但你应该检查这些字符,如果它们存在,你知道文件从
'r'n'r'n
之后开始
你的请求有问题。您尝试PUT请求的方式是错误的。
如何使用PHP通过HTTP PUT接收文件
把
这直接补充了GET。其中GET请求指示方法指定的位置返回文档请求URI中的响应体,则PUT方法指示服务器应该将数据存储在请求体中的位置
这意味着,您可能不会在单个PUT请求中包含多部分请求。必须有单一的内容类型。(Multipart用:------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);
}
听起来好像有东西被添加到输出中。在文本编辑器中打开ZIP文件,检查服务器/PHP生成的警告消息/无意输出的内容。