Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to access REQUEST_FILENAME via PHP? [duplicate]

I'm trying to understand the following htaccess rule in more detail:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
  RewriteRule (.+) index.php?p=$1 [QSA,L]
</IfModule>

Specifically, I'm trying to understand how REQUEST_FILENAME works. There are several resources which I've found discussing this, from the mod_rewrite docs to answers here on Stack Overflow. But none seem to be addressing exactly what I'm looking for which is how do I take a closer look at the REQUEST_FILENAME variable in order to see it's value?

Typically, when I want to look at a variable being referenced in .htaccess, I will use print_r to look at the $_SERVER global to see what the server things those values are:

echo "<pre>";
print_r($_SERVER);
echo "</pre>";
die('fin');

That can help me see values such as $_SERVER['REQUEST_URI'] above. But it doesn't seem that REQUEST_FILENAME is available in any of the PHP $GLOBALS in my current environment. I do see a value for SCRIPT_FILENAME, and several sources say that these two values are equal, but it's not clear if they are substitutes or if REQUEST_FILENAME falls back to SCRIPT_FILENAME if the first is not present.

I have been able to output the REQUEST_FILENAME value by updating the htaccess rule slightly to output the value in the URL, changing the last line to:

RewriteRule (.+) index.php?p=%{REQUEST_FILENAME} [R=302,QSA,L]

But why isn't this value available anywhere in PHP? Is there anything I'm overlooking that can help me understand where this variable is stored and how to view it's value via PHP?

like image 802
Ben Parizek Avatar asked Apr 10 '13 18:04

Ben Parizek


1 Answers

From RewriteCond

REQUEST_FILENAME
The full local filesystem path to the file or script matching the request, if this has already been determined by the server at the time REQUEST_FILENAME is referenced. Otherwise, such as when used in virtual host context, the same value as REQUEST_URI. Depending on the value of AcceptPathInfo, the server may have only used some leading components of the REQUEST_URI to map the request to a file.

and from $_SERVER

'SCRIPT_FILENAME'
The absolute pathname of the currently executing script.

This will be the same (the full path to the script), if the REQUEST_URI actually corresponds to an existing file.

If it doesn't, REQUEST_FILENAME will be just REQUEST_URI and SCRIPT_FILENAME will be the name of the PHP script executing. $_SERVER['REQUEST_URI'] will beREQUEST_FILENAME (aka REQUEST_URI).

In your case, SCRIPT_FILENAME will always be /path/to/index.php and REQUEST_FILENAME/REQUEST_URI will be accessible through $_SERVER['REQUEST_URI'].

Update:

REQUEST_URI will never be a filename, because it lacks the document root prefix. When you use

RewriteCond %{REQUEST_URI} !-f

the condition will always be true, even when the requested URL would match an existing file. The following RewriteRule will always be executed, although it should call another PHP script or serve a HTML, CSS or image file.

Update:

To actually answer the question.

But why isn't this value available anywhere in PHP?

REQUEST_FILENAME isn't available in PHP, because it isn't in the environment or in the request's headers.

All you can see in PHP, is either some environment variable or in the headers or something PHP can deduce itself. Since PHP doesn't try or isn't able to make the connection between the request URI and some filename, you cannot access it anywhere. The REQUEST_FILENAME might be anywhere in the filesystem after all.

You can, however, put it in the environment yourself

RewriteRule (.+) index.php?p=$1 [QSA,L,E=REQUEST_FILENAME:%{REQUEST_FILENAME}]

and access it in PHP as $_SERVER['REDIRECT_REQUEST_FILENAME'].

like image 119
Olaf Dietsche Avatar answered Oct 18 '22 14:10

Olaf Dietsche