# [PATCH] PHP_IMAP New Function "imap_partialbody" to fetch chunks of a MIME attachment

- Thread: https://externals.io/message/12173
- Original archive: https://news-web.php.net/php.internals/12173
- Started by Uwe Schindler on 2004-08-15T15:32:25+00:00
- Messages: 4
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #12173 — Uwe Schindler — 2004-08-15T15:32:25+00:00

URL: https://externals.io/message/12173#12173

How about the idea to make a function like "imap_getbodystream(...)" that 
returns a PHP stream that can be read with `fread()` etc. and then closed by 
 `fclose()`?. This could be done by using Wez's PHP stream wrappers in PHP5 
(even in PHP4.3).

Uwe

At 00:47 15.08.2004, you wrote:
>This new function is intended to add "chunking" capability to fetching 
>attachments from an email using the IMAP library. Currently the attachment 
>fetch is done with imap_fetchbody , and is placed entirely in memory, ergo 
>- if the attachment is larger than the available memory it will fail.
>
>This function has the following prototype - string 
>imap_partialbody(resource stream_id, int msg_no, int section, int start, 
>int len [, int options])
>It's exactly like  imap_fetchbody, except it adds the parameters  start 
>(for the start position offset) and len (for the number of bytes to 
>retrieve). I've also made sure that the correct checks for message number 
>are in the code (as per the recent change to imap_fetchbody).
>
>It uses the function "mail_partial_body" in the C Client, which doesn't 
>appear in any of the very dated documentation, but I found a few postings 
>by Mark Crispin explaining how to use it, and it's also been used in pine. 
>One complication is that it uses a callback to populate the buffer, but I 
>found some hints on how to use a "spare pointer " element in the IMAP 
>stream structure from a post by him in one of the online IMAP forums here 
>- http://www.webservertalk.com/message299504.html
>
>Obviously the benefit is that a new attachment retrieval could be 
>implemented in webmail such as IMP that doesn't require the memlimit on 
>the server to be set to some absurd value, and would be less likely bring 
>the server to its knees when some idiot mails a 50M video to a group of 
>his friends. Note however c-client is still greedy about memory for its 
>cache (theres nothing that can be done about that) - but this doesn't 
>figure in the PHP memlimit.
>A snippet of some resulting PHP using the function (struct is the return 
>from imap_fetchstructure - note I haven't put anything in to decode the 
>structure or errorcheck the return for brevity). CHUNKSIZE is how much to 
>fetch at a time (100K works quite well)
>$size=$struct->parts[$partindex]->bytes;
>$fp=fopen($attachfile,"w");
>for ($i=0;$i<$size;$i+=CHUNKSIZE)
>{
>      $len = (($size-$i)<CHUNKSIZE) ? $size-$i:CHUNKSIZE;
>     $pbody = imap_partialbody($imap,$msgno,$partno,$i,$len);
>      fwrite($fp,$pbody);
>}
>
>You will find this code works fine on a large attachment, and doesn't blow 
>the memlimit when its set to the default of 8M.
>The next problem of course is that php/php_imap doesn't have a streamed 
>Base64 decoder - though I've used a simple command line one quite effectively.
>
>I'm guessing if this is of interest, it will be of most interest to the 
>HORDE/IMP team?
>
>Crispin Olson

-----
Uwe Schindler
thetaphi@php.net - http://www.php.net
NSAPI SAPI developer
Erlangen, Germany

---

## #12176 — Crispin Olson — 2004-08-15T16:50:43+00:00

URL: https://externals.io/message/12173#12176 · In reply to: #12173

Uwe Schindler wrote:

> How about the idea to make a function like "imap_getbodystream(...)" 
> that returns a PHP stream that can be read with `fread()` etc. and then 
> closed by `fclose()`?. This could be done by using Wez's PHP stream 
> wrappers in PHP5 (even in PHP4.3).
>
> Uwe

Uwe,
Not a bad idea, and I had thought of it too. Surely I need to be looking 
at the "Streams API for extension authors" though, rather than the 
wrapper functions if I want to create and maintain my own stream?
 
At this point I've kept it simple, because for the most part, php_imap 
is a simple wrapper layer onto the UW c-client, and that is also true 
for this function.

Crispin

---

## #12177 — Uwe Schindler — 2004-08-15T17:20:38+00:00

URL: https://externals.io/message/12173#12177 · In reply to: #12176

This would be also interesting:
For decoding base64 binarys you could use the string.base64 stream filter 
then (PHP5)! :)

Uwe

At 18:50 15.08.2004, Crispin Olson wrote:
>Uwe Schindler wrote:
>
> > […]
>
>Uwe,
>Not a bad idea, and I had thought of it too. Surely I need to be looking 
>at the "Streams API for extension authors" though, rather than the wrapper 
>functions if I want to create and maintain my own stream?
>At this point I've kept it simple, because for the most part, php_imap is 
>a simple wrapper layer onto the UW c-client, and that is also true for 
>this function.
>
>Crispin
>
>--
>
>
>

-----
Uwe Schindler
thetaphi@php.net - http://www.php.net
NSAPI SAPI developer
Erlangen, Germany

---

## #12178 — Crispin Olson — 2004-08-15T17:29:02+00:00

URL: https://externals.io/message/12173#12178 · In reply to: #12177

Uwe Schindler wrote:

> This would be also interesting:
> For decoding base64 binarys you could use the string.base64 stream 
> filter then (PHP5)! :)
>
> Uwe
>
That does make sense - I didn't realise there was a base64 stream filter 
in PHP5 (I'm still using 4.3)
That would make it possible to hook a stream directly up to an 
attachment, so an attachment download in webmail could be achieved 
without any PHP memory overhead whatsoever, and 3 lines of code - sweet.

Crispin
