【问题标题】:Read raw request body for multipart/form-data with php in PUT, PATCH, DELETE ... request在 PUT、PATCH、DELETE ... 请求中使用 php 读取 multipart/form-data 的原始请求正文
【发布时间】:2016-10-31 03:22:18
【问题描述】:

我正在从头开始编写一个 restful api 库,现在我遇到了一个常见问题:从请求中读取 multipart/form-data 的原始数据。

对于 POST 请求,我知道我应该使用 $_FILE / $_POST 变量。但是,如果存在 PUTPATCH 或除 POST 之外的任何请求类型怎么办?

  • 这种情况可能吗?
  • 如果是这样,我如何阅读原始正文 内容,因为根据documentation 它不是 在php://input 可用?

注意:我已经搜索过输入格式以及如何读取它,我只想访问 RAW 数据

【问题讨论】:

  • 我已经测试过,php://input 可用于 PUT 请求,并且在文档中没有看到任何矛盾的地方
  • “根据文档,它在 php://input 中不可用”——我在文档中看不到它在哪里说的。
  • 如果有帮助请查看此链接,link
  • 嗨。请检查一下:php://input is not available with enctype="multipart/form-data". 在本段末尾:php.net/manual/en/wrappers.php.php#wrappers.php.input
  • @CarlosCarucce,如果您使用的是 apache,则有一个技巧 here 可以更改“multipart/form-data”以强制 php 获取实际数据(因此您可以使用php://input)。既然你说你正在开发一个开源库,我认为你不会喜欢那个解决方案,但它值得一读。

标签: php rest httprequest


【解决方案1】:

但是如果有 PUT、PATCH 或其他任何请求类型怎么办? 而不是 POST?

好吧,既然你是设计API的人,那么你是决定它是否只接受POSTPUTPOST + PUT 或任何其他请求标头组合。

API 不应设计为“接受并尝试处理”第三方应用提交给您的 API 的所有内容。以 API 接受请求的方式准备请求是应用程序(我的意思是连接到 API 的应用程序)的工作。

请记住,启用多种请求方法(尤其是那些必须区别对待的方法)会带来多种处理请求的方法(例如安全性、类型等)。 这基本上意味着要么你必须巧妙地设计一个请求处理流程,要么你会遇到不同请求类型不同调用的 API 方法的问题,这会很麻烦。

如果您需要获取请求的原始内容 - @Adil Abbasi 似乎在正确的轨道上(就解析 php://input 而言)。 但请注意 php://input 不适用于 enctype="multipart/form-data" as described in the docs

<?php
$input = file_get_contents('php://input');
// assuming it's JSON you allow - convert json to array of params
$requestParams = json_decode($input, true);
if ($requestParams === FALSE) {
   // not proper JSON received - set response headers properly
   header("HTTP/1.1 400 Bad Request"); 
   // respond with error
   die("Bad Request");
}

// proceed with API call - JSON parsed correctly

如果您需要使用 enctype="multipart/form-data" - 请阅读 I/O Streams docs 中的 STDIN,然后像这样尝试:

<?php
$bytesToRead = 4096000;
$input = fread(STDIN, $bytesToRead ); // reads 4096K bytes from STDIN
if ($input === FALSE) {
   // handle "failed to read STDIN"
}
// assuming it's json you accept:
$requestParams = json_decode($input , true);
if ($requestParams === FALSE) {
   // not proper JSON received - set response headers properly
   header("HTTP/1.1 400 Bad Request"); 
   // respond with error
   die("Bad Request");
}

【讨论】:

  • 感谢您对 I/O 流的引用。实际上,我正在编写一个开源库,this 是我处理“multipart/form-data”请求的方式......因为它可以在第三方应用程序中使用,我想支持这些请求.
  • 正如我所说的 - 这是你的选择,也许这是一个合理的选择。只要记住仔细设计请求处理过程,就可以了。
【解决方案2】:

PUT 数据来自标准输入,只需将原始数据解析为变量:

        // Parse the PUT variables
        $putdata = fopen("php://input", "r");
        $put_args    = parse_str($putdata);

或者喜欢:

        // PUT variables
        parse_str(file_get_contents('php://input'), $put_args);

【讨论】:

    【解决方案3】:

    您可以利用此代码 sn-p,将参数设置为数组格式。

      $params = array();
      $method = $_SERVER['REQUEST_METHOD'];
    
      if ($method == "PUT" || $method == "DELETE") {
          $params = file_get_contents('php://input');
    
          // convert json to array of params
          $params = json_decode($params, true);
      }
    

    【讨论】:

    • downvaote 的原因?
    • @CarlosCarucce 请试试这个更新的代码 sn-p,对我来说工作正常 :)
    • 嗨。非常有趣,但是,'multipart/form-data' 请求呢?顺便说一句,我很抱歉,但不是我否决了它。
    • 我建议最好使用 base64 编码(图像数据),可能您正在寻找在这个 put 调用上上传图像。
    • 我正在编写一个可以接收任何类型内容的请求解析器(假设它接收完整的表单,而不仅仅是文件内容)。当它是一个文件时,它会创建一个“UploadedFile”对象表示。当它计算输入数据时,它会被解析为一个数组,就像 php 本身对 POST 请求所做的那样
    猜你喜欢
    • 2012-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 2012-01-19
    • 2019-12-13
    相关资源
    最近更新 更多