readfile() is the easier approach to this if you're not concerned with utilizing HTTP Content-Range headers ( http://us.php.net/manual/en/function.readfile.php). It writes the content of the file directly to the output buffer, avoiding the memory limits altogether.
However, if you're going to be serving even remotely large files, You'll want to take a look at using Content-Range. This will allow clients to break downloads up into manageable sizes and/or resume downloads. The browser will cache the downloads in chunks, remembering which portions have been downloaded. It will then fill in the pieces as it needs by providing your script with a content byte range. E-Tag headers will also be highly beneficial for you here. (there's an example of how to handle E-Tag headers in the readfile() user notes.) Here's a high-level example of byte serving: http://www.coneural.org/florian/papers/04_byteserving.php and there's another example in the readfile() user comments as well (search for SmartReadFile) Beau On Tue, Sep 22, 2009 at 3:56 PM, Mac Newbold <[email protected]> wrote: > Today at 2:40pm, Andrew kain said: > > > Hello list, I am looking for the best way to serve secure sensitive files > > uploaded to a PHP server. I only want authenticated users to be able to > view > > these files (jpg, pdf, etc). Usually anyone can view files uploaded to > any > > directory. I'm guessing the best way would be to upload the files outside > of > > the web root that way they are not directly accessable from the web > server. > > My question is, what would be the next step? To authenticate the session > and > > mod re-write to direct the user to the secured area? Can anyone with > > any experience with this please give some pointers? thank you much in > > advance. > > There are a variety of options, as William Attwood explained. One > difference is whether it is okay for someone to be able to retrieve the > file by knowing its link. One level of security is to turn off directory > indexing (if necessary) and use PHP to ask for a password before showing > them the links to the files. But once they have the links, they'd be able > to request them directly. > > The path you mention above, of putting the files outside webroot, is a > stronger solution. As you mentioned, you authenticate the session first, > but I don't think you can rewrite them to the secured area because it is > outside the webroot. Generally the way you'd do this is by having the PHP > script hand the file back to the user rather than having Apache do it > directly. > > The PHP script to hand off the file is pretty simple. Usually you'd set it > up to check permissions and display an error or a login form if they don't > have access. If they pass the access checks, you use header() to set your > HTTP response headers (controlling things like saving vs opening the file, > content type, caching controls, etc.), then you pass the contents of the > file back. One way is fpassthru() but it turns out to be a memory hog, > reading the whole file into memory before sending it out, which means you > often run into the 8MB default memory limit. Another way is to do it chunk > by chunk like so: > > $fp = fopen($path,'r'); > while (!feof($fp)) { > $data = fread($fp,1048576); > echo $data; > } > fclose($fp); > > As you can see, that one reads 1MB at a time. > > Thanks, > Mac > > -- > Mac Newbold Code Greene, LLC > CTO/Chief Technical Officer 44 Exchange Place > Office: 801-582-0148 Salt Lake City, UT 84111 > Cell: 801-694-6334 www.codegreene.com > > _______________________________________________ > > UPHPU mailing list > [email protected] > http://uphpu.org/mailman/listinfo/uphpu > IRC: #uphpu on irc.freenode.net > -- Beau D. Scott Software Engineer _______________________________________________ UPHPU mailing list [email protected] http://uphpu.org/mailman/listinfo/uphpu IRC: #uphpu on irc.freenode.net
