1

My PHP script is receiving large data (100 - 500 MB) from a client. I want my PHP script run fast, without using too much memory.

To save traffic, I don't use Base64 or form data. I send binary data directly in a POST request.

The data consists of two parts: 2000 Bytes header, and the rest, that has to be stored as a file on the server.

$fle = file_get_contents("php://input",FALSE,NULL,2000);
file_put_contents("file.bin", $fle);

The problem is, that file_get_contents ignores the offset parameter, and reads the data from byte 0. Is there any better way to do it?

** I don't want to read the whole data and slice off the last N-2000 bytes, as I am afraid it would use too much memory.

8
  • substr($fle, 2000) Commented Jan 7, 2019 at 18:15
  • First of all don't create another variable -$fle- file_put_contents("file.bin", file_get_contents("php://input",FALSE,NULL,2000)); Commented Jan 7, 2019 at 18:21
  • 2
    @Accountantم still reads everything into memory before flushing it to disk. Commented Jan 7, 2019 at 18:32
  • @Sammitch Yes I know, this will just prevent creating another copy of the data in the memory. great answer you post by the way, I did similar buffer before Commented Jan 7, 2019 at 18:39
  • 1
    @Accountantم ah, I misread your previous comment. It should be 1x with or without the variable assignment. Commented Jan 7, 2019 at 19:04

1 Answer 1

3

Use the lower-level file IO functions and read/write a little bit at a time.

$bufsz = 4096;

$fi = fopen("php://input", "rb");
$fo = fopen("file.bin", "wb");

fseek($fi, 2000);

while( $buf = fread($fi, $bufsz) ) {
  fwrite($fo, $buf);
}

fclose($fi);
fclose($fo);

This will read/write in 4kB chunks.

Sign up to request clarification or add additional context in comments.

5 Comments

Things to note with this is your execution time - ensure you have set this in your php ini. Great answer with explanation though! Didn't know you could specify the size to read consistently, always used filesize() as the second arg. Great to know for future reference.
BTW. is there a simple way to read N bytes from $fi ? In my case, fread() often returns less than the value of the second parameter.
@IvanKuckir that should only ever happen once per file, at most, and only ever at the end of the file when it's not an even multiple of the buffer size. This is fine. Any other observed case is a different problem that needs to be addressed.
@Sammitch I ran your code with $bufsz = 1000000; (which is larger than the size of my file). The file is saved, but it never reads more than 8192 bytes at once.
@IvanKuckir php://input is a special stream and may have some peculiarities associated with it. Unless you have some special requirement to hold ~1MB of data in memory for some reason, a buffer size of 8192 bytes or smaller should work just fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.