How to Flatten a PHP POST Array

The situation is this: You have a PHP script that takes POST data, and you need to pass that data on to a remote server. How do you do it? Well, there are three options:
  • Use $_SERVER['HTTP_RAW_POST_DATA'] but only if php.ini has that enabled - not usually the case. You could try asking your host, "Can I set 'always populate raw post data' in the php.ini file?"
  • Use php://input but this doesn't work if the POST data is multipart, ie, containing a file upload.
  • Code it yourself. This option is described here.
The complication lies in PHP's ability to structure POST (and GET) data as multi=dimensional arrays (arrays of arrays (of arrays, if you like)), so unstitching all that nested structure is a bit fiddly - and it's recursive. Here is the code to produce an associative array of name-value pairs, where both name and value are a simple string:
function flattenpost($data) { if(!is_array($data)) return urlencode($data); $ret=array(); foreach($data as $n => $v) { $ret = array_merge($ret,_flattenpost(1,$n,$v)); } return $ret; } function _flattenpost($level,$key,$data) { if(!is_array($data)) return array($key=>$data); $ret=array(); foreach($data as $n => $v) { $nk=$level>=1?$key."[$n]":"[$n]"; $ret = array_merge($ret,_flattenpost($level+1,$nk,$v)); } return $ret; } $newpost=flattenpost($_POST);
"What's the point in that", I hear you cry, "We still have an associative array!" Well, true, but this is the ideal solution if you're intending to submit the data using cURL (since it accepts an array input to the CURLOPT_POST option). It's also necessary to maintain an associative array if you need to blend in file upload data in the $_FILES array.

If you definitely only want the raw POST string with no blending of uploaded files, then you may as well use php://input.



It's quiet in here...Add your comment