I’m trying create a caching system for an "on demand" PHP image resizer.
I need to be able to check if the following file and query string exists in cache:
https://www.example.com/images/img.jpg?w=400&h=300&fit=crop
My PHP script generates the cached file by replacing all special chars (?,&,=) with underscore.
This is what the cached object looks like:
/cache/images/img.jpg_w_400_h_300_fit_crop
How do I check if the requst + query exists in /cache
as file and serve it if it does?
What I currently have that works for files without query vars is this:
# if file exists in /cache/ directory
# serve file from /cache/ directory
RewriteCond %{DOCUMENT_ROOT}/cache/$1 -f
RewriteRule ^(.*)$ /cache/$1 [L,QSA]
I tried with something like this but it doesn’t work because I suck at htaccess/regex 🙂
RewriteCond %{QUERY_STRING} ^(.*)(:?&|?|=)(.*)$
RewriteCond %{DOCUMENT_ROOT}/cache/$1_%1_%2 -f
RewriteRule ^(.*)$ /cache/$1 [L]
2
Answers
With your shown samples, could you please try following. Please make sure to clear your browser cache before testing your URLs.
You could do the same thing in
.htaccess
. This then handles "any number"1 of URL parameters (since you’ve stated this is variable in comments).Try the following script near the top of your
.htaccess
file. Ideally, this needs to be near the top due to the recursive nature of the search/replace looping.I chose to use an environment variable
IMAGE_CACHE_FN
to hold the value of the image cache filename as it is constructed, rather than modify the query string or URL-path in-place since I expect you are probably using these later in your PHP script.1 I’ve limited this to 50 recursive "loops" max (which equates to about 26 URL parameters) in the script above. This is identified by the
N=50
flag on the secondRewriteRule
.A potential caveat with this is if the URL parameters are supplied in a different order then you’ll naturally get a different cache filename for essentially the same resource. Although the same will apply to your PHP script, unless you are ordering the parameters first? (But then you potentially have issues with duplicate images and caching unless you redirect the request.) I’m assuming you are supplying the URL params in a specific order.
You can potentially order the URL parameters in
.htaccess
, but it can get cumbersome…