5

我正在尝试使用 HTTP PUT 上传文件。
在阅读了一下之后,似乎该$_FILES数组只有 POST 和multipart/form-data. 使用 PUT 时,我需要手动读取php://input以获取数据。两种方法都不起作用。

我尝试了以下选项,并希望您有任何提示:

curl --upload avatar.jpg http://api.test.com/user/dsadasdsa
curl -X PUT -F "filedata=@avatar.jpg" http://api.test.com/user/dsadasdsa

我的 PHP 文件试图打印它,但返回一个空字符串:

echo file_get_contents("php://input");

我开始认为这可能是一个 Nginx 问题,缺少 PUT DELETE 支持并安装了 nginx-extras 以及将以下内容添加到我的 nginx 配置中,但不幸的是,这也无济于事。

root /var/www/;

dav_methods PUT DELETE MKCOL COPY MOVE;

create_full_put_path on;
dav_access group:rw all:r;
4

6 回答 6

3

我有一些调试的想法。

做一个var_dump(file_get_contents('php://input'));而不是回声。根据参考

此函数可能返回布尔值 FALSE,但也可能返回计算结果为 FALSE 的非布尔值。请阅读有关布尔值的部分以获取更多信息。使用 === 运算符测试此函数的返回值。

如果你得到一个bool(false)作为输出,有一些错误导致你无法阅读php://input——很可能是一个 PHP 问题。如果您得到string(0) "",则php://input(不再?)中什么都没有,这使得这更有可能是 nginx 问题。

此外,根据php://参考资料,您不能使用php://inputwith enctype="multipart/form-data"。你确定不用那个?如果更熟悉,您也可以尝试使用 HTML 文件。

默认情况下,您还可以检查错误日志/var/log/nginx/error.log。此外,请检查 HTTP 响应代码。是200吗?如果不是,它是一个有用的代码吗?

于 2013-06-15T12:49:28.700 回答
2

您使用的选项 -F 导致 curl 使用 Content-Type multipart/form-data 发布数据(请参阅 man curl)。

您可以使用 --data-binary 选项,如:

curl -X PUT --data-binary "@avatar.jpg" http://api.test.com/user/dsadasdsa

-d 选项仅适用于文本,可能会损坏您的数据。

在我的测试中,以下命令给出了相同的结果。

curl --upload "avatar.jpg" http://api.test.com/user/dsadasdsa

这是我的服务器

<?php
echo "request method : " . $_SERVER['REQUEST_METHOD'] . "\n";
echo "dump files ";
var_dump($_FILES);

$putdata = fopen("php://input", "r");
while ($data = fread($putdata, 1024)) {
      echo $data . "\n";
}
?>
于 2013-06-19T14:26:01.720 回答
1

Nginx 支持所有 http 动词(put、delete、options 等)。因此,您不需要在 nginx 中进行任何特殊设置。

以下工作(我正在使用 php5.4 服务器来轻松测试):

添加这个名为 put.php 的简单测试 php 脚本

$putdata = fopen("php://input", "r");
while ($data = fread($putdata, 1024)) {
      echo $data . "\n";
}

从 put.php 的同一个文件夹启动一个 php 服务器:

php -S localhost:5000

发出 PUT curl 请求:

curl -d "@/path/to/put.php" -X PUT http://localhost:5000/put.php

这将打印 put.php 的文件内容

[更新]

如果您想使用 php 将 curl 请求发送到 restful api 站点,我建议您使用Guzzle,您不必记住所有这些 curl 选项。

于 2013-06-15T13:37:28.417 回答
0

两种方法都不起作用

我从未尝试过使用 PHP 实现 DAV,但我可以向您保证,带有文件上传的 POST 可以正常工作,即使使用 nginx 也是如此。

curl --上传头像.jpg http://api.test.com/user/dsadasdsa

我原以为这会起作用-您的日志显示了什么?你试过'--trace'吗?

curl -X PUT -F "filedata=@avatar.jpg" http://api.test.com/user/dsadasdsa

将 -F 标志与 curl 一起使用意味着使用 multipart/form-data 编码将文件作为 POST 变量上传 - 这对 PUT 请求没有任何意义。

于 2013-06-21T14:57:04.837 回答
0

您是否通过在 nginx 后面放置一种不同类型的 webapp 并测试它是否可以处理 PUT 上传来消除 PHP 作为问题的原因?一个非常短的 Python Flask 应用程序可以让您测试另一种语言的 PUT 上传。

于 2013-06-22T01:26:02.663 回答
0

如果您尝试向服务器创建 PUT 请求并且无法从 php 包装器中读取,请确保:

  1. 你有正确的 PUT 请求。完成标题和内容(使用 PHP 和 CURL 发出 PUT 请求

  2. 您的服务器接受 PUT 请求。

  3. 您的 php 文件可以先读取简单的 PUT 请求(没有上传部分)

您可能还想查看 php://input ( http://php.net/manual/en/wrappers.php.php ) 中指示的“注释”。除此之外,这可能是服务器上的问题。

于 2013-06-20T02:07:00.850 回答