php - 使用 PHP 手动解析原始多部分/表单数据数据

标签 php http parsing curl

我似乎找不到这个问题的真正答案,所以我开始了:

如何在 PHP 中解析 multipart/form-data 格式的原始 HTTP 请求数据?我知道如果格式正确,原始 POST 会自动解析,但我所指的数据来自 PUT 请求,PHP 不会自动解析该请求。数据是多部分的,看起来像:

------------------------------b2449e94a11c
Content-Disposition: form-data; name="user_id"

3
------------------------------b2449e94a11c
Content-Disposition: form-data; name="post_id"

5
------------------------------b2449e94a11c
Content-Disposition: form-data; name="image"; filename="/tmp/current_file"
Content-Type: application/octet-stream

�����JFIF���������... a bunch of binary data

我像这样用 libcurl 发送数据(伪代码):

curl_setopt_array(
  CURLOPT_POSTFIELDS => array(
    'user_id' => 3, 
    'post_id' => 5, 
    'image' => '@/tmp/current_file'),
  CURLOPT_CUSTOMREQUEST => 'PUT'
  );

如果我删除 CURLOPT_CUSTOMREQUEST 位,请求将作为服务器上的 POST 处理,并且一切都被解析得很好。

有没有办法手动调用 PHP 的 HTTP 数据解析器或其他一些好的方法? 是的,我必须以 PUT 的形式发送请求 :)

最佳答案

编辑 - 请先阅读: 这个答案在 7 年后仍然经常被点击。从那以后我再也没有使用过这段代码,也不知道这些天是否有更好的方法。请查看下面的评论,并知道此代码在许多情况下不起作用。使用风险自负。

--

好的,根据 Dave 和 Everts 的建议,我决定手动解析原始请求数据。在搜索了大约一天后,我没有找到任何其他方法。

我得到了一些帮助 thread .我没有像在引用的线程中那样篡改原始数据的运气,因为这会破坏正在上传的文件。所以这都是正则表达式。这没有经过很好的测试,但似乎适用于我的工作案例。事不宜迟,希望有一天这可能对其他人有所帮助:

function parse_raw_http_request(array &$a_data)
{
  // read incoming data
  $input = file_get_contents('php://input');
  
  // grab multipart boundary from content type header
  preg_match('/boundary=(.*)$/', $_SERVER['CONTENT_TYPE'], $matches);
  $boundary = $matches[1];
  
  // split content by boundary and get rid of last -- element
  $a_blocks = preg_split("/-+$boundary/", $input);
  array_pop($a_blocks);
      
  // loop data blocks
  foreach ($a_blocks as $id => $block)
  {
    if (empty($block))
      continue;
    
    // you'll have to var_dump $block to understand this and maybe replace \n or \r with a visibile char
    
    // parse uploaded files
    if (strpos($block, 'application/octet-stream') !== FALSE)
    {
      // match "name", then everything after "stream" (optional) except for prepending newlines 
      preg_match('/name=\"([^\"]*)\".*stream[\n|\r]+([^\n\r].*)?$/s', $block, $matches);
    }
    // parse all other fields
    else
    {
      // match "name" and optional value in between newline sequences
      preg_match('/name=\"([^\"]*)\"[\n|\r]+([^\n\r].*)?\r$/s', $block, $matches);
    }
    $a_data[$matches[1]] = $matches[2];
  }        
}

引用使用(以免过多复制数据):

$a_data = array();
parse_raw_http_request($a_data);
var_dump($a_data);

关于php - 使用 PHP 手动解析原始多部分/表单数据数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5483851/

相关文章:

php - 如何以静默模式执行脚本以摆脱浏览器挂起

http - 是否可以通过 CoAP 传输文件?

c++ - Boost::Spirit - on_error 不打印

php - 屏幕抓取JS页面

parsing - Stanford Parser : How to include the punctuations?

php - 在 PHP & MySQL 中使用两个表来显示一个循环结果

php - 选择 Linux 进行开源开发

php - 多级选择框

android - java.lang.NoClassDefFoundError : Failed resolution of: Lorg/apache/http/params/BasicHttpParams;

node.js - 在node.js中发送HTTP响应