RE: [PECL-DEV] RFC for Post Parse Extension
| From: | Wez Furlong | Date: | Sun, 06 Jun 2004 16:14:17 +0000 |
| Subject: | RE: [PECL-DEV] RFC for Post Parse Extension | ||
| References: | 1 | Groups: | php.pecl.dev |
| Request: | Send a blank email to pecl-dev+get-732@lists.php.net to get a copy of this message | ||
IMO, this should be done in a generic way:
1/ Have an .ini option to skip the built-in mime parser.
2/ Expose mime parser functions so that the content can be parsed from any
stream.
So, a slightly modified version of your example:
$fp = fopen('php://input', 'r');
// open a magical parser stream/resource
$parser = postparser_init($fp);
// get the content-type, length and encoding headers
$headers = postparser_get_headers($parser);
While ($token = postparser_get_token($parser)) {
switch ($token['type']) {
case POSTPARSER_VARIABLE:
$_POST[$token['name']] = stream_get_contents($parser);
break;
case POSTPARSER_FILE:
// $token contains content-type and filename etc.
$fp = fopen($tmpfile, 'w');
stream_copy_to_stream($tmpfile, $parser);
break;
}
}
$parser = null;
The important points here are:
$parser is custom stream type that references the input file pointer; whenever
you call postparser_get_token() it is rewound to reference the start of the
post data item. Subsequent read calls will pull data out until the end of
that item, where the $parser stream will register EOF.
I've used stream_copy_to_stream() and stream_get_contents() to show how few
lines are needed to process the data in bulk; if you are updating a progress
bar of some kind, you will want to use fread() yourself in a loop.
--Wez.
> 3.0 Example
>
> /*
> * Set up the environment and checks to see if multipart/form
> * exists.
> */
> $pph = postparse_init();
>
> if ( $pph) {
> /*
> * POST data has been sent from client
> */
>
> while (! $rc = postparse_eof($pph) ) {
> switch ($rc) {
>
> case POSTPARSE_VARIABLE:
>
> /*
> * if no limit is desired for size of value
> * a loop would be more appropriate
> */
> postparse_read($pph, 1024, $value);
> break;
>
> case POSTPARSE_FILE:
>
> $tmpname = tempnam('/tmp');
> $fp = fopen($tmpname, 'w');
> while ($bread = postparse_read($pph, 1024, $buf) ) {
> fwrite($fp, $buf);
> }
> flcose($fp);
>
> break;
> }
> }
> postparse_close($pph);
> }