【问题标题】:Curl PUT request with file upload to PHP将文件上传到 PHP 的 Curl PUT 请求
【发布时间】:2013-06-22 09:26:02
【问题描述】:

我正在尝试使用 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;

【问题讨论】:

  • @Gordon - 谢谢。我知道那个页面,但它只告诉我在 PHP 端做什么(我已经在做)。并没有真正告诉我我在卷曲方面做错了什么。
  • 另外,尝试运行手册中完全相同的代码只会创建一个空文件。所以我很确定我的 CURL 请求是错误的。
  • 我也是从那里来的......我开始认为错误在于 Nginx 需要特定安装以支持 PUT/DELETE,我将尝试这样做。感谢您的帮助!

标签: php curl upload nginx put


【解决方案1】:

我有一些调试的想法。

使用var_dump(file_get_contents('php://input')); 而不是回显。根据reference

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

如果您得到一个bool(false) 作为输出,则有一些错误导致您无法读取php://input - 很可能是PHP 问题。如果您收到string(0) "",则php://input 中没有任何内容(还有吗?),这更有可能是 nginx 问题。

另外,根据php:// reference,您不能将php://inputenctype="multipart/form-data" 一起使用。你确定不用那个?如果更熟悉的话,您也可以尝试使用 HTML 文件。

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

【讨论】:

  • 不幸的是,我还没有机会对此进行测试,但您的回答似乎是迄今为止最彻底的一个。谢谢!
  • @ShaiMishali 如果您已经测试过,请告诉我。并感谢代表:)
【解决方案2】:

您使用的选项 -F 导致 curl 使用 Content-Type multipart/form-data POST 数据(请参阅 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";
}
?>

【讨论】:

    【解决方案3】:

    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 选项。

    【讨论】:

      【解决方案4】:

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

      1. 您有正确的 PUT 请求。完成标题和内容 (Making a PUT request with PHP and CURL)

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

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

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

      【讨论】:

        【解决方案5】:

        这两种方法都不行

        我从未尝试过使用 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 一起使用意味着将文件作为 POST 变量上传,使用 multipart/form-data 编码 - 这对 PUT 请求没有任何意义。

        【讨论】:

          【解决方案6】:

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

          【讨论】:

            猜你喜欢
            • 2021-12-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-02-22
            • 1970-01-01
            • 2017-11-02
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多