我有以下代码,只是为了从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文档和十几个帖子进行了梳理,但我无法弄清楚为什么这两种方法会有所不同。
有什么见解?
感谢。
答案 0 :(得分:1)
听起来有些东西被添加到输出中。在文本编辑器中打开ZIP文件,检查内容,查看服务器/ PHP生成的警告消息/无意输出。
答案 1 :(得分:1)
^M
是窗口行结束字符CR LF
(0x0D 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);
}