Last active
March 17, 2023 01:59
-
-
Save cwhsu1984/3419584ad31ce12d2ad5fed6155702e2 to your computer and use it in GitHub Desktop.
parse multi-dimensional form-data from PATCH request
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// The code is inspired by the following discussions and post: | |
// http://stackoverflow.com/questions/5483851/manually-parse-raw-http-data-with-php/5488449#5488449 | |
// http://www.chlab.ch/blog/archives/webdevelopment/manually-parse-raw-http-data-php | |
/** | |
* Parse raw HTTP request data | |
* | |
* Pass in $a_data as an array. This is done by reference to avoid copying | |
* the data around too much. | |
* | |
* Any files found in the request will be added by their field name to the | |
* $data['files'] array. | |
* | |
* @param array Empty array to fill with data | |
* @return array Associative array of request data | |
*/ | |
function parse_raw_http_request($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); | |
// content type is probably regular form-encoded | |
if (!count($matches)) | |
{ | |
// we expect regular puts to containt a query string containing data | |
parse_str(urldecode($input), $a_data); | |
return $a_data; | |
} | |
$boundary = $matches[1]; | |
// split content by boundary and get rid of last -- element | |
$a_blocks = preg_split("/-+$boundary/", $input); | |
array_pop($a_blocks); | |
$keyValueStr = ''; | |
// 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); | |
$a_data['files'][$matches[1]] = $matches[2]; | |
} | |
// 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); | |
$keyValueStr .= $matches[1]."=".$matches[2]."&"; | |
} | |
} | |
$keyValueArr = []; | |
parse_str($keyValueStr, $keyValueArr); | |
return array_merge($a_data, $keyValueArr); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment