Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/244.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP文件上传PUT请求更改文件,而POST不更改文件_Php_Apache - Fatal编程技术网

PHP文件上传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(

我有下面的代码,只是为了从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文件,根据
解压
,在开头增加了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);
}