readfile() or file_get_contents()?

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

readfile() or file_get_contents()?

Post by s.dot »

I've figured out that I'm going to use a centralized script to handle all image requests. The script will pull images based on $_GET paramaters from different directories.

Now, this script could be being called hundreds of time per minute from hotlinking of images (think image hosting type site).

Which would be more friendly to my server. readfile() or file_get_contents()? Or, would it really even matter?
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

file_get_contents()

EDIT: Crap, I've no idea actually.
ev0l
Forum Commoner
Posts: 56
Joined: Thu Jun 21, 2007 1:50 pm

Re: readfile() or file_get_contents()?

Post by ev0l »

scottayy wrote:I've figured out that I'm going to use a centralized script to handle all image requests. The script will pull images based on $_GET paramaters from different directories.

Now, this script could be being called hundreds of time per minute from hotlinking of images (think image hosting type site).

Which would be more friendly to my server. readfile() or file_get_contents()? Or, would it really even matter?
readfile() .

file_get_contents() has the overhead of creating a PHP string as well as allocating memory to put that string in.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

file_get_contents() has the overhead of creating a PHP string as well as allocating memory to put that string in.
Yeah I thought that too, which is why I retracted my last assertion but then there's something in the back of my brain telling me it's file_get_contents() or maybe that could be file_get_contents() versus fopen().
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

If you need to read a string into memory, use file_get_contents(); but for this case, you'll want to use readfile(). Note that if you can manage it, some mod_rewrite kung fu will probably get the job done in a much more efficient manner.
ev0l
Forum Commoner
Posts: 56
Joined: Thu Jun 21, 2007 1:50 pm

Post by ev0l »

ole wrote:
file_get_contents() has the overhead of creating a PHP string as well as allocating memory to put that string in.
Yeah I thought that too, which is why I retracted my last assertion but then there's something in the back of my brain telling me it's file_get_contents() or maybe that could be file_get_contents() versus fopen().
Using fopen/fread and placing the contents of a file into a PHP string is likely to be less efficient than file_get_contents because file_get_contents is written entirely in C and skirts the issue of converting to a PHP string until the last minute. Of course the inefficiency might be entirely acceptable depending on the situation.

In any case my mantra is, code for clarity first, efficiency second.
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Post by Benjamin »

The Manual wrote: file_get_contents() is the preferred way to read the contents of a file into a string. It will use memory mapping techniques if supported by your OS to enhance performance.
You guys should really have a look at the manual once in a while :wink:
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

Yes, astions, but I do not want to read the contents of a file into a string. I simply want to output it to the browser. And the manual page for readfile() says:
Reads a file and writes it to the output buffer.
Seems like that's what I would want. Not sure what the output buffer is exactly, and how much of it I can use at any given time. =/
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Post by Benjamin »

It directly outputs it, either way it's in memory. Your going to have to send headers first anyway.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

I do not know enough about PHP's internals to say this definitively, but presumably the content will be streamed: PHP will not have any more in its memory at a time than it needs to; as it sends out data, it gets flushed from the memory and more stuff is read. In olden days, when memory was scarce, this concept was crucial to ensure that you didn't run out of memory (TeX is a big stickler about this thing... heck, it'll complain if the lines in your input files are too long).
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

Reading the PHP manual's comments, it appears that readfile indeed reads the entire thing into memory. :-O

Maybe we should go back to the days of fopen and fread. :-)
miro_igov
Forum Contributor
Posts: 485
Joined: Fri Mar 31, 2006 5:06 am
Location: Bulgaria

Post by miro_igov »

You can do a benchmark.

Code: Select all

$start = time();
readfile('filename.jpeg');
$end = time();

echo "Operation took ".$end-$start." seconds";
Then do the same for file_get_contents() . If you can try the benchmark with small and large files and compare the performance of the 2 read functions.
Z3RO21
Forum Contributor
Posts: 130
Joined: Thu Aug 17, 2006 8:59 am

Post by Z3RO21 »

Unless you want to manipulate the output before you send it to the output buffer I would use readfile()

The output buffer is what is going to be sent to the end user.

echo, for example, sends information to the output buffer. As for working with the output buffer check out the output buffer PHP functions. http://us.php.net/manual/en/ref.outcontrol.php
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

Use file_get_contents(). It uses memory mapping and according to the docs is binary safe!

From Wikipedia:
Memory mapping is often faster than standard file based access for two reasons. The first is that the standard file I/O access routines require a system call (which is slower than a local function call). Memory mapping allows applications to ideally minimize the number of system calls for I/O. The other benefit is that most operating systems provide shared access to the underlying buffer cache (the kernel's cache of the file data), meaning that no copy be done to user space. Memory copying can be a time consuming portion of file I/O.
Cheers :)
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

I personally would use fread() iteratively so you only pull a small amount of data from the file into memory at any one time.
Post Reply