On 05/01/2012 07:27 AM, Rasmus Lerdorf wrote: > On 05/01/2012 06:39 AM, Paul Reinheimer wrote: >> Hi Larry, >> >>> Fascinating. I even verified the md5sum of the file I got on the other end >>> just to be sure. I'll hold off on the blog post then. :-) I look forward >>> to your test setup. >> >> The server in question is still on PHP 5.2.13 >> >> Script: >> <?php >> ini_set('memory_limit', '8M'); >> $name = uniqid() . ".zip"; >> header('Content-type: application/zip'); >> header("Content-Disposition: attachment; filename=\"$name\""); >> readfile('../../filestorage/4f9e9e3b9bcff.zip'); >> >> File Information: >> [user@host public]$ ls -alh ../../filestorage/4f9e9e3b9bcff.zip >> -rw-r--r-- 1 apache apache 27M Apr 30 10:14 >> ../../filestorage/4f9e9e3b9bcff.zip >> >> Error: >> [Tue May 01 09:30:48 2012] [error] [client 198.136.162.2] PHP Fatal >> error: Allowed memory size of 8388608 bytes exhausted (tried to >> allocate 27617281 bytes) in >> /home/lots/of/path.org/stuff/public/rf822.php on line 6 >> >> >> I'll try something newer, but I wanted to prove myself not crazy and >> do it on the server in question first. > > That's odd, because PHP 5.2 has identical code in this respect. Wez > committed these changes in 2002: > > https://github.com/php/php-src/commit/a662f012bba5a6fdc50533673f3fff47bf9af219#diff-5 > > So it has been like this for quite a while. Does that server have > implicit unlimited output buffering turned on in your ini file?
And actually, that patch just made it use streams. Even before the internal streams API the function worked the same way. In PHP 4.2 it used php_passthru_fd which looked like this: https://github.com/php/php-src/blob/PHP-4.2.0/ext/standard/file.c#L1526 Sascha added the mmap implementation we still use today in 1999: https://github.com/php/php-src/commit/dda0b783df7d849df01fa831febbc1e34b5b8dd3 But even prior to that readfile would still buffer in 8k chunks. The PHP 2.0.1 implementation (very scary to look at code I wrote 17 or 18 years ago): /* * Read a file and write the ouput to stdout */ void ReadFile(void) { Stack *s; char buf[8192],temp[8]; FILE *fp; int b,i, size; s = Pop(); if(!s) { Error("Stack error in ReadFile"); return; } if(!*(s->strval)) { Push("-1",LNUMBER); return; } #if DEBUG Debug("Opening [%s]\n",s->strval); #endif StripSlashes(s->strval); #if PHP_SAFE_MODE if(!CheckUid(s->strval,1)) { Error("SAFE MODE Restriction in effect. Invalid owner of file to be read."); Push("-1",LNUMBER); return; } #endif fp = fopen(s->strval,"r"); if(!fp) { Error("ReadFile(\"%s\") - %s",s->strval,strerror(errno)); Push("-1",LNUMBER); return; } size= 0; php_header(0,NULL); while((b = fread(buf, 1, sizeof(buf), fp)) > 0) { for(i = 0; i < b; i++) PUTC(buf [i]); size += b ; } fclose(fp); sprintf(temp,"%d",size); Push(temp,LNUMBER); } -Rasmus -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php