2

Okay so I am trying to read a 91kb file in chunks of 1048576 bytes ( 1 MB ) which is supposed to read the file instantaneously in one chunk, however this is not what I'm getting

public function uploadTmpFileFromXHRStream(){
    header('Content-type: text/html; charset=utf-8');
    function output($val)
    {
        echo $val;
        flush();
        ob_flush();
    }

    $in = fopen('php://input', 'r');
    $tmpFileId = uniqid(null,true);
    $out = fopen($tmpFileId.'_'.$_SERVER['HTTP_X_MFXHRFILEUPLOAD'], 'x');
    while($data = fread($in,1048576)){
        fwrite($out, $data);
        output(1);
        sleep(2);
    }

}

On the other side I have set up javascript to listen on xhr.readystatechange at readyState==3 and simply just log output to the console. What I have in the console is this:

200 OK 24,02s   
1
11
111
1111
11111
111111
1111111
11111111
111111111
1111111111
11111111111
111111111111

There're 12 iterations in the while loop, the exact file size from php://input is 93335. I'm pretty confused, why is this happening?

php_nub_qq
  • 15,199
  • 21
  • 74
  • 144
  • buffered input stream? – Mark Baker Dec 23 '13 at 15:58
  • check `var_dump(feof($in))` inside that loop. I'm willing to bed that the input file is 0-byte so the fread returns instantly with "nothing". – Marc B Dec 23 '13 at 15:58
  • From what I see at http://www.php.net/manual/en/function.fread.php, php's fread is more like UNIX read, not C fread. That is, it's expected to read less than requested size in many situations. – Anton Kovalenko Dec 23 '13 at 15:58
  • @MarkBaker I'm uploading the file as in this answer http://stackoverflow.com/a/11771857/2415293 – php_nub_qq Dec 23 '13 at 16:02
  • @MarcB I get `bool(false)` all the way :/ – php_nub_qq Dec 23 '13 at 16:02
  • @AntonKovalenko I'm not sure I understand, I've now read the manual for the nth time but still.. How am I to determine the size of the chunk? – php_nub_qq Dec 23 '13 at 16:06
  • @php_nub_qq seems like if it's pipe or socket (as in your case), you have to live with whatever chunk size `fread` decides to return (up to requested length). – Anton Kovalenko Dec 23 '13 at 16:12
  • @php_nub_qq I don't know whether you can control read buffering in PHP, but if you can, setting buffer size to 1 MB would make chunk size predictable. – Anton Kovalenko Dec 23 '13 at 16:14

1 Answers1

3

php://input is a read-only stream. From fread

if the stream is read buffered and it does not represent a plain file, at most one read of up to a number of bytes equal to the chunk size (usually 8192) is made; depending on the previously buffered data, the size of the returned data may be larger than the chunk size.

php://input is a buffered stream which does not represent a plain file. fread is reading one chunk (8192 bytes) at a time.

File size / chucks = read cycle count

93335 / 8192 = 11.4

Binary Alchemist
  • 1,600
  • 1
  • 13
  • 28