0

I have faced memory limit problem while reading and outputting an image file. What I do is - check if file exists and if not I get the file from a remote repository, save it and then output it. The question is how do I output the file contents and skip getting the file into memory?

$file = 'someimagefile.jpg';

if(file_exists($file)){
    exit(file_get_contents($file));
}
else{
    $fileContents = file_get_contents('http://somedomain.com/files/'.$file);
    $handle = fopen($file, 'w+');
    fwrite($handle, fileContents);
    fclose($handle);
    
    exit($fileContents);
}

As far as I understand the exit(file_get_contents($file)) gets the file into memory. I know there is a way to stream a file, but I am not aware of the function mechanics. Will this code do the same thing without using the memory?:

if (file_exists($file)) {
    $file = fopen($file, 'r');
    exit(stream_get_contents($file));
}
else{
    $file = fopen('http://somedomain.com/files/'.$file, 'r');
    $dest = fopen($file, 'w+');
    
    
    stream_copy_to_stream ( $file , $dest );
    
    fclose($file);
    fclose($dest);
}
Timur Gafforov
  • 771
  • 3
  • 10
  • 28
  • You can check out [readfile()](https://www.php.net/manual/en/function.readfile.php): _"readfile() will not present any memory issues, even when sending large files, on its own. If you encounter an out of memory error ensure that output buffering is off with ob_get_level()."_ – M. Eriksson Jul 10 '20 at 06:47
  • Using `exit()` with the file contents seems a very odd idea to output the file. You should also try and set the headers to reflect the type of data you are sending (if you know it). – Nigel Ren Jul 10 '20 at 06:57
  • 2
    @MagnusEriksson [this article](https://stackoverflow.com/questions/6627952/why-does-readfile-exhaust-php-memory) says "PHP has to read the file and it writes to the output buffer" - readfile will still exhaust memory – Timur Gafforov Jul 10 '20 at 07:03
  • @NigelRen this is just a part of the whole code. The question is about saving server memory, not about image headers. Thanks for your input, though – Timur Gafforov Jul 10 '20 at 07:05
  • @NigelRen [this](https://stackoverflow.com/questions/2028898/php-output-file-on-disk-to-browser) is a totally different question with answers that do not fix my problem. Both readfile and fpassthru do exhaust the memory. The question still remains unsolved – Timur Gafforov Jul 10 '20 at 07:12
  • If you run with enough users, any method will have problems. As the link you point to about `readfiles()` states that it is not `readfiles()` that runs out of memory, it's the number of times you call it from different users that cause the problem. But then again if you have large arrays, this will still cause a problem. – Nigel Ren Jul 10 '20 at 07:16
  • Perhaps https://stackoverflow.com/questions/11679723/alternative-to-stream-copy-to-stream-php may give some more information. – Nigel Ren Jul 10 '20 at 07:18
  • @NigelRen no. It doesn't solve the problem. Can anyone tell if the solution with streams I have provided works or not? – Timur Gafforov Jul 10 '20 at 07:30
  • 1
    You are storing those images, so that in the future the will be directly available under the originally requested URL, yes? Well then I’d say, _The Future is Now!_ - the image URL should be available right after you stored it, so maybe redirect to that URL, instead of having PHP pipe through the image data in the first place? […] – CBroe Jul 10 '20 at 07:46
  • 1
    […] I don’t know how common clients react when you redirect them to the exact same URL they originally requested, you’d have to test that. Otherwise, you could append a parameter to the URL (although that could mean a bit of a hit regarding caching, if the original image URL gets requested on the next page again.) – CBroe Jul 10 '20 at 07:46
  • @CBroe my God this is embarassing. I remember header('location: ...') didn't use to work with img src. But it's working fine now. Is that just for new browsers? Or any browsers actually support that? – Timur Gafforov Jul 10 '20 at 09:56
  • 1
    I am not aware of any problems in that regard, ever. Redirecting is a basic part of HTTP, and I have never heard of browsers having problems with that in particular when it comes to images. Maybe what you’re remembering there included some very specific circumstances, but in general, this is not a problem at all. – CBroe Jul 10 '20 at 10:14

0 Answers0