I have a lot of images on my website, they are pulled from an image server onto the main server when requested to save disk space at my hosting server.
To achieve this I have an entry in my .htaccess
file that basically internally redirects people from /images/image.jpg
to download.php
which checks to see if th开发者_Go百科e file exists. If the file exists it serves it up (code below) else it'll use CURL
to pull in the remote file then redirect to itself header("Location: ".$_SERVER['REQUEST_URI']);
so that it then shows the image.
Is it inefficient to serve images to the browser in such a manner? Is it faster to let the web server do it naturally? The code for reading and showing the file is below.
$file_extension = strtolower(substr(strrchr($filename,"."),1));
header("Pragma: public");
header("Content-Type: image/jpg");
header("Content-length: ".filesize($filename));
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filename));
readfile("$filename");
Would I be better off (read: more efficient) NOT using a htaccess redirect but actually modifying my 404 page to check for image specific 404's and then download them?
Here is the .htaccess
that defines the redirect to download.php
^images/([0-9]+)_([a-z0-9_]+).jpg$ /download.php?id=$1
It's a little unclear what you mean by 'redirect to itself'. Is there any reason your download.php can't use CURL to grab the image from the remote server and then serve it up using your code sample in the same way? Why would it need to redirect?
It's best not to use the PHP engine to serve images if it can be avoided, as Apache can do this much more efficiently by itself. You also lose some of Apache's default behaviour, e.g. your code example isn't sending last modified headers or handling etags, so if a user revisits the same page they're going to end up downloading the image again instead of using a cached version.
Your suggested alternative approach would be a little better, as once your script had downloaded the image the first time, all subsequent requests would be served by Apache directly. Just make sure you're not sending 404 headers along with the image.
Alternatively it is possible to check whether files exist using htaccess, so you could only redirect requests for non existent images to download.php and not have to modify your 404 script. Something like this (untested):
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/images
RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule ^.*$ download.php [NC,L]
this means: if the REQUEST_URI starts with /images, and the filename does not match an existing file on the file system, rewrite it to download.php.
I'd also recommend looking into X-Sendfile, an Apache module which makes it very easy to serve images (and other binary data). Using it in PHP is as simple as sending a header containing the path to the file:
header("X-Sendfile: /home/whatever/public/images/something.jpg");
Apache then does all the rest of the work for you - reading and outputting the file contents and sending all the appropriate headers. The module isn't usually enabled by default so you might need to install it or check with your host.
You'd be better of with just prefixing your rewrite with:
RewriteCOnd %{REQUEST_FILENAME} !-f
... and if you download the file in download.php, why not just show it to the user? No need for a redirect.
I think directly serve images would always be faster than your code which wouldn't let to use the browser cache but I'm not sure.
As far as the connection from client to browser, it's exactly as quick as serving the data normally. Apache doesn't care where the information came from, it just sends the data it's handed. If the data is the result of reading a file or the result of a 10-million like C++ program, it's all just bits.
Where your method is slower is when it's pulling the image from the image server. This essentially means that the image is being sent twice. Once from image server -> host server, then again from host server -> client. If your image server and host server are on the same Local Area Network with relatively few nodes and a very fast connection then this may not be a noticeable difference. If the image server is located on a different network or if the image file is very large, the difference can be dramatic, and may not be worth the cost to disk space.
精彩评论