0

This is what I need to achieve:

Request: http://www.example.com/image5.jpg

Should rewrite, for example:

RewriteRule ([^.]+)\.jpg$ /image.php?image=$1

Now, in my image.php, how do I serve the image, if I know where it is?

For example:

<?php

$path = '/images/5/2/3/1/small/latest/'.$_GET['image'].'.jpg';

?>

What is the best way to handle this request, so that it behaves like a image file (sends an image header) and displays the image?

There are various alternatives around the net, mainly X-Sendfile and readfile(), but I'm not sure what is the optimal solution and why.

Frantisek
  • 7,485
  • 15
  • 59
  • 102
  • I guess it depends what you mean by "optimal": Most efficient? Easiest to write? Hardest to determine that PHP is involved, for some kind of security-by-obscurity? Most portable (e.g. `X-Sendfile` won't work on all web servers)? It is a common mistake to think there is a single "best" way of achieving every task, when in fact it nearly always depends on the context. – IMSoP Apr 05 '14 at 22:09
  • @IMSoP: 1) I can deploy X-Sendfile on my webserver. 2) I don't need security by obscurity. People can see it's a PHP script. 3) Doesn't have to be easiest to write. I need to serve files with various names for Google purposes (for example '1-black-table.jpg'), but not have to rename them on my HDD (keep it as 1.jpg). – Frantisek Apr 05 '14 at 22:12
  • You've gone ahead and told me some things that *aren't* important, but you still haven't explained what you *do* want. If you can write two lines of PHP code that do what you want, what it is it about them that you want to improve? What do "best" and "optimal" mean to you? Most of the thoughts I have are around *additional* things to consider - sending cache-control headers, checking security, handling missing files, etc - but I'm not sure how to make that an answer to your question. – IMSoP Apr 05 '14 at 22:25
  • @IMSoP: I want to avoid filling up my RAM or taking up too much CPU time, that's all. I've never served image files other than automatically with apache by directly linking them. – Frantisek Apr 05 '14 at 22:33

2 Answers2

0

Assuming web server can still serve the images directly via full path, I would just redirect directly to image:

header("Location: /images/5/2/3/1/small/latest/{$_GET['image']}.jpg");
exit;

The exit is good to have after sending headers. Also, make sure you do not send any other output, as header will not work then.

ek9
  • 3,392
  • 5
  • 23
  • 34
  • 1
    I don't think 302 redirects are the optimal solution. The links never behave as real image files and Google might have a problem with indexing them properly. – Frantisek Apr 05 '14 at 21:52
  • "Also, make sure you do not send any other output, as header will not work then." This sentence is slightly muddled. I *think* what you're trying to say is that when creating an *HTTP redirect*, you shouldn't also send output. However, there are many uses of `header()` which have nothing to do with redirects. – IMSoP Apr 05 '14 at 22:06
0

The fastest way to do this is to leverage the operating systems zero-copy support, whereas the file is sent by telling the network driver to move data directly from the OS file system buffer and onto the network. This way, no RAM coping is necessary, and the bottleneck will be in your network bandwidth.

I can't find any mention of PHP supporting this, however, which means that if you must serve the file with PHP, you will have to copy the file from the OS file cache into a PHPs memory space, and then have PHP ask the driver to copy it.

I would assume the built in method for doing that will be the most performant way to do it: http://php.net/manual/en/function.http-send-file.php

Jacob Davis-Hansson
  • 2,603
  • 20
  • 26