Score:1

What does %{REQUEST_FILENAME}.ext mean? Why the extra .ext ending?

dj flag

The %{REQUEST_FILENAME} contains a string like this:

/web/webroot/index.php

I see a lot of people recommend testing if a file exists and has a .php extension like this:

RewriteCond %{REQUEST_FILENAME}.php -f

Isn't the .php after %{REQUEST_FILENAME} redundant? The variable should already contain the .php, right?

Seems like adding .php after %{REQUEST_FILENAME} would make the TestString check add an extra .php, like this:

/web/webroot/index.php.php

I'm missing something simple, I'm sure of it, but I just don't know what it is.

The context is this:

RewriteCond %{THE_REQUEST} ^.*?\.php [NC]
RewriteRule ^ - [R=404,NE,L]

RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_FILENAME}.php [L]
Score:1
kz flag

Isn't the .php after %{REQUEST_FILENAME} redundant? The variable should already contain the .php, right?

Well, yes and no, it depends what you are trying to do.

RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_FILENAME}.php [L]

This rule allows you to request extensionless URLs. eg. /index or /foo and this internally rewrites the request to /index.php and /foo.php respectively.

In this instance, REQUEST_FILENAME is a string of the form /web/webroot/index. So, it's testing that /web/webroot/index.php exists before rewriting to the same. If you were to request /index.php then the condition fails and no rewrite occurs (which is correct).

However, this rule isn't strictly correct and could cause a rewrite-loop under certain conditions. See the following related question:

Jeff avatar
dj flag
I see you know your stuff. I'll stare at this for a few more hours until I figure it out. I think you're saying the variable is modified by appending the `.ext`, but I can't find this behavior documented anywhere except on SE forums. EDIT: Yeah, okay, I get it. Thanks!
kz flag
@Jeff The variable itself (ie. `REQUEST_FILENAME`) isn't modified, just the _TestString_ (first argument to the `RewriteCond` directive) - as you state in the question. It's basically testing whether the requested URL + `.php` exists as a physical file. Although, `REQUEST_FILENAME` isn't strictly the correct variable to use here (although works in _most_ cases), as mentioned in the linked question. (`REQUEST_FILENAME` is the "file" that the requested URL maps to.)
Jeff avatar
dj flag
Well since I, of course, want to use strictly the correct variables in my code, is this the one: `%{DOCUMENT_ROOT}%{REQUEST_URI}.php -f`?
kz flag
@Jeff Yes, and change the `RewriteRule` _substitution_ string accordingly. ie. `RewriteRule ^ %{REQUEST_URI}.php [L]`
Jeff avatar
dj flag
Awesome, thanks very much!
kz flag
@Jeff The regex `!\.\w{2,4}$` excludes all requests that already include what _looks like_ a file extension. It's just an optimisation, to prevent all static resources (images, CSS, JS, etc) from being unnecessarily tested to see if `image.jpg.php` exists etc. (filesystem checks are relatively expensive). Files don't _normally_ have two file extensions like `exists.qqq.php`, so wouldn't normally be a problem. But it is just an optimisation so is safe to remove. You could achieve a similar optimisation by excluding the subdirectory where all your static assets are stored.
Jeff avatar
dj flag
Good stuff. Doesn't the `RewriteCond` line before the exclusion regex already exclude all those extra tests to the other static resources (besides .html files)?
kz flag
@Jeff The `RewriteRule` directive is processed first. Only when the `RewriteRule` _pattern_ matches are the preceding _conditions_ processed. If the `RewriteRule` _pattern_ is not successful then the entire rule is skipped and processing continues...
Jeff avatar
dj flag
Wow, I did not know that. Thanks again!
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.