2

I have a raw form-data that look like this:

------------V2ymHFg03ehbqgZCaKO6jy
Content-Disposition: form-data; name="intro"

O
------------V2ymHFg03ehbqgZCaKO6jy
Content-Disposition: form-data; name="title"

T
------------V2ymHFg03ehbqgZCaKO6jy
Content-Disposition: form-data; name="apiKey"

98d32fdsa
------------V2ymHFg03ehbqgZCaKO6jy
Content-Disposition: form-data; name="method"

/media/add
------------V2ymHFg03ehbqgZCaKO6jy
Content-Disposition: form-data; name="upload_field"; filename="original_filename.png"
Content-Type: image/png


------------V2ymHFg03ehbqgZCaKO6jy--

(In place of second line of upload_field there are data of this file (invisible here). So my question is:

How to parse above data to have a table:

$result['intro'] 

and so on with data inside?

Tom Smykowski
  • 25,487
  • 54
  • 159
  • 236
  • possible dupe of http://stackoverflow.com/questions/3290132/read-post-request-parameters-properly-in-php-for-request-more-than-1450-b – fabrik Jul 20 '10 at 13:42
  • @fabrik No, in the question that you linked is very differed. And it's my question too. Please read more carefully. – Tom Smykowski Jul 20 '10 at 13:51
  • I saw that one is your question too. One thing i don't see: the difference. Both question asks to read these values. – fabrik Jul 20 '10 at 13:54
  • @fabrik In this question I as how to parse raw post data manually. And in the question you linked I ask how to do so that PHP will parse POST request properly on it's own. Do you see the difference now? – Tom Smykowski Jul 20 '10 at 14:02
  • 1
    Not really. Good luck, tomaszs. – fabrik Jul 20 '10 at 14:12
  • @fabrik Thank you, either question I get proper answer it will help a lot. I sure hope that someone knows solution for either of this problems. Kind regards. – Tom Smykowski Jul 20 '10 at 16:30

3 Answers3

1
$boundary = "------------V2ymHFg03ehbqgZCaKO6jy"; // take this from content-type
$rawfields = explode($boundary,$data);
array_pop($rawfields); // drop the last -- piece
foreach ( $rawfields as $id=>$block )
{
    list($mime,$content) = explode("\r\n\r\n",$block,2); // I think it's <cr><lf> by standards, maybe check!
    if ( preg_match('/name="([^"]*)"/i',$mime,$match) )
    {
        $result[$match[1]] = $content;
        // todo: do funky stuff with other fields
    } else {
        $result[] = $content; // just in case...
    }
}

presto.

edit: you should also trim off the newline from each content block, but rtrim will chop more than one newline, so you have to get a little more creative.

mvds
  • 45,755
  • 8
  • 102
  • 111
  • Best exploding the string by new lines then get the first line as boundary, most of the time you will not know the boundry ! - an ragards to cf/nl try standerdizing the new lines `str_replace(array("\r","\n"),"\r\n",$string);` – RobertPitt Jul 20 '10 at 14:22
  • this is flawed anyway, should `preg_split("/-+$boundary/",$data)` instead of exploding. replacing newlines doesn't seem wise since you would be altering content as well. But then again the whole setup of parsing this by hand is flawed. – mvds Jul 20 '10 at 16:32
1

The content-type of the overall document is multipart, with the parts being separated by the given boundary.

Each part, or message, within the multipart document is in a standard message format: header lines, followed by a blank line, followed by a sequence of bytes representing the content of that part. Both HTTP and SMTP work like this.

With header lines like Content-Disposition: form-data; name="title", you have to be careful with the name because it could be encoded (think about how to represent an arbitrary value, such as one containing a double quote mark or a newline).

yfeldblum
  • 65,165
  • 12
  • 129
  • 169
0

I was dealing with a similar problem myself and wrote my own version of mvds's code to also work with binary files. Here's the thread for future reference.

Community
  • 1
  • 1
Christof
  • 3,777
  • 4
  • 37
  • 49