PHP文件上传PUT请求更改文件,而POST不更改文件
我有下面的代码,只是为了从PUT请求或POST请求中获取一个文件并将其复制到服务器PHP文件上传PUT请求更改文件,而POST不更改文件,php,apache,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(
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文件,根据解压
,在开头增加了165个字节。它仍然成功地解压,但是警告消息不会出现在发布的文件中。我真正掌握的另一条线索是文件大小相差211字节
我已经仔细阅读了php文档和十几篇文章,但我不明白这两种方法为什么会有所不同
有什么见解吗
谢谢。听起来好像输出中添加了一些内容。在文本编辑器中打开ZIP文件,检查服务器/PHP生成的警告消息/意外输出的内容。
^M
是windows的行尾字符CR LF
(0x0D 0x0A
或\r\n
)
打开流时,$putdata=fopen(“php://input“,“r”)代码>
首先发送头,然后发送文件(头和正文由\r\n\r\n
指定)
我不知道是哪个部分的设置导致了错误,但您应该检查这些字符,如果它们存在,您知道文件在\r\n\r\n
之后启动
你的请求有问题。你试图提出请求的方式是错误的
PUT
这直接补充了GET。其中,GET请求指示
服务器应在指定的位置返回文档
请求URI在响应体中,PUT方法指示
服务器应将数据存储在请求正文中的以下位置
由请求URI指定
这意味着,在单个PUT请求中可能没有多部分请求。
必须有一个单一的内容类型。(多部分由以下符号表示:----WebKitFormBoundaryhPjNpS0gBhbCC8aR
)
在POST请求中,允许多部分(请考虑:enctype='multipart/formdata'
)
带有文件的put请求不得包含任何其他内容。也就是说,如果你想把一个文件加上变量,这些变量需要附加到URI中,但不像POST那样,附加到主体中
使用可能的解决方法更新(我知道这是一个肮脏的解决方案,请不要怪我……):
在文本编辑器中打开修改后的ZIP文件。我猜某个进程正在将一条消息添加到缓冲区。你是对的cat
转储一堆不可读的内容,但是当我查看vim时,我可以看到一些额外的文本<代码>----WebKitFormBoundaryhPjNpS0gBhbCC8aR^M内容处置:表单数据;name=“package”;filename=“warmup.0.6.5.1.nupkg”^M内容类型:application/octet stream ^M^M
现在我要想办法忽略这些内容……这很有趣。当你通过POST抓取原始输入流时,它的标题和内容边界似乎被剥离了,但通过PUT它仍然存在。你确定你在处理POST并将其放在客户端吗?我正在使用google chrome的高级REST客户端应用程序。到目前为止,它一直对我很有用,因此我更倾向于认为问题在于我对PHP如何处理数据的理解,但现在看来,它对请求的编码方式可能是罪魁祸首。经过进一步调查,其他生成PUT请求的客户机也添加了此标头数据,因此,我回到了最初的问题,即在处理文件之前剥离这些页眉数据。有用的信息,但我更感兴趣的是完全删除这些不需要的页眉和页脚内容,因为我不能确定每个请求的页眉和页脚是否相同。是的,实际上,最终将提供请求的是windows程序nuget.exe。不幸的是,我无法更改请求的创建方式,因此我必须找出服务器端如何删除它。@Jason我更新了我的答案。。。这不是库的问题,而是您发出put请求的方式。嗯,正如我提到的,我对put请求的创建没有实际控制权。使用nuget程序,我得到以下标题:------------------------------------8d16e4de44cb30d^M内容配置:表单数据;name=“package”;filename=“package”^M内容类型:应用程序/八位字节流^M^M
。因为我无法更改它的发送方式,所以我必须弄清楚如何在服务器端删除这些内容。@JasonBray我宁愿修复程序中的错误,也不愿实现一个workarround,它可能会在以后中断或导致其他问题。这个nuget程序是什么?
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);
}