You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@httpd.apache.org by Ian Brandt <ia...@ianbrandt.com> on 2007/05/12 11:38:58 UTC

[users@httpd] Can't set environment variable in per-birectory rewrite

Hi,

I'm trying to implement the front controller pattern for a simple PHP  
site, while simultaneously leveraging mod_rewrite for some run-of-the- 
mill rewriting beforehand as well.  Apache 2.2.4 & PHP 5.2.2.  My  
simplified rules in .htaccess at present are as follows:

-----
# Rewrite any requests ending with '.htm', '.html' to end with '.php'.
RewriteRule ^(.*)\.htm[l]?$ $1.php [NS]

# Verify the requested file exists, and if so end by sending the  
request to our front controller.
# The front controller will be injecting the requested page into a  
layout, so grab the request URI
# as it was rewritten just prior to the rewrite to the front  
controller itself, and stuff it in the
# server environment variable "REWRITTEN_REQUEST_URI".
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.+)$ frontcontroller.php [NS,E=REWRITTEN_REQUEST_URI:$1]

# Serve anything left directly, 404 with Apache's ErrorHandler if not  
found, or the like.
-----

My issue is that for a request such as "index.html"  
REWRITTEN_REQUEST_URI ends up being "frontcontroller.php", not  
"index.php" as I had hoped.

My rewrite log is below.  As I understand it the issue is the two  
phase processing mod_rewrite must do for per-directory context rules  
as described here: <http://httpd.apache.org/docs/2.2/rewrite/ 
rewrite_tech.html>.  Despite my hopes the nosubreq flag doesn't seem  
to apply in this special case, and so my variable is being  
overwritten with the undesired value from the second pass.

I tried a using a conditional rewrite that wouldn't match for the  
second "frontcontroller.php" pass:

RewriteCond %{REQUEST_FILENAME} !frontcontroller.php
RewriteRule ^(.+)$ - [E=REWRITTEN_REQUEST_URI:$1]

The variable set according to the logs, and was not overwritten on  
the second pass, but it wasn't available to my PHP script.  I'm  
assuming that implies that first pass really is a "fake" one,  
environment variables set in it are only scoped private to the first  
pass itself?

To get to my question is there any way to capture the rewritten URI  
part way through the first pass?

A workaround would be to not do the .htm[l] to .php rewriting and the  
like in Apache, but instead handle it all in my PHP front controller,  
but I'd rather leverage the existing functionality than duplicate it  
from scratch.  Moving the rewriting to the per-server context is also  
very undesirable as it prevents use of the pattern by those who don't  
have access to the server config.

Thanks,

Ian


[rid#18d0450/initial] (3) [perdir /mydocroot/] strip per-dir prefix: / 
mydocroot/index.html -> index.html
[rid#18d0450/initial] (3) [perdir /mydocroot/] applying pattern '^(.*) 
\.htm[l]?$' to uri 'index.html'
[rid#18d0450/initial] (2) [perdir /mydocroot/] rewrite 'index.html' - 
 > 'index.php'
[rid#18d0450/initial] (3) [perdir /mydocroot/] add per-dir prefix:  
index.php -> /mydocroot/index.php
[rid#18d0450/initial] (3) [perdir /mydocroot/] strip per-dir prefix: / 
mydocroot/index.php -> index.php
[rid#18d0450/initial] (3) [perdir /mydocroot/] applying pattern '^(.+) 
$' to uri 'index.php'
[rid#18d0450/initial] (4) [perdir /mydocroot/] RewriteCond: input='/ 
mydocroot/index.php' pattern='-f' => matched
[rid#18d0450/initial] (2) [perdir /mydocroot/] rewrite 'index.php' ->  
'frontcontroller.php'
[rid#18d0450/initial] (5) setting env variable  
'REWRITTEN_REQUEST_URI' to 'index.php'
[rid#18d0450/initial] (3) [perdir /mydocroot/] add per-dir prefix:  
frontcontroller.php -> /mydocroot/frontcontroller.php
[rid#18d0450/initial] (2) [perdir /mydocroot/] strip document_root  
prefix: /mydocroot/frontcontroller.php -> /frontcontroller.php
[rid#18d0450/initial] (1) [perdir /mydocroot/] internal redirect  
with /frontcontroller.php [INTERNAL REDIRECT]
[rid#18bd758/initial/redir#1] (3) [perdir /mydocroot/] strip per-dir  
prefix: /mydocroot/frontcontroller.php -> frontcontroller.php
[rid#18bd758/initial/redir#1] (3) [perdir /mydocroot/] applying  
pattern '^(.*)\.htm[l]?$' to uri 'frontcontroller.php'
[rid#18bd758/initial/redir#1] (3) [perdir /mydocroot/] strip per-dir  
prefix: /mydocroot/frontcontroller.php -> frontcontroller.php
[rid#18bd758/initial/redir#1] (3) [perdir /mydocroot/] applying  
pattern '^(.+)$' to uri 'frontcontroller.php'
[rid#18bd758/initial/redir#1] (4) [perdir /mydocroot/] RewriteCond:  
input='/mydocroot/frontcontroller.php' pattern='-f' => matched
[rid#18bd758/initial/redir#1] (2) [perdir /mydocroot/] rewrite  
'frontcontroller.php' -> 'frontcontroller.php'
[rid#18bd758/initial/redir#1] (5) setting env variable  
'REWRITTEN_REQUEST_URI' to 'frontcontroller.php'
[rid#18bd758/initial/redir#1] (3) [perdir /mydocroot/] add per-dir  
prefix: frontcontroller.php -> /mydocroot/frontcontroller.php
[rid#18bd758/initial/redir#1] (1) [perdir /mydocroot/] initial URL  
equal rewritten URL: /mydocroot/frontcontroller.php [IGNORING REWRITE]

---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
   "   from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] Can't set environment variable in per-directory rewrite

Posted by Ian Brandt <ia...@ianbrandt.com>.
On May 12, 2007, at 10:50 AM, Joshua Slive wrote:

> I don't know the exact problem here, but I can suggest a more typical
> way to get around this:
> Simple use something like
> RewriteRule ^(.+)$ frontcontroller.php/$1  
> [NS,E=REWRITTEN_REQUEST_URI:$1]
> or
> RewriteRule ^(.+)$ frontcontroller.php?Rewritten_request_uri=$1 [QSA]


Using the query string does the trick.  I'll file the environment  
variable issue as a bug as it doesn't seem like the desired behavior.

Thanks,

Ian

---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
   "   from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] Can't set environment variable in per-birectory rewrite

Posted by Joshua Slive <jo...@slive.ca>.
On 5/12/07, Ian Brandt <ia...@ianbrandt.com> wrote:

> RewriteRule ^(.+)$ frontcontroller.php [NS,E=REWRITTEN_REQUEST_URI:$1]

I hate dealing with per-directory rewrites myself. Too darn complex.

I don't know the exact problem here, but I can suggest a more typical
way to get around this:
Simple use something like
RewriteRule ^(.+)$ frontcontroller.php/$1 [NS,E=REWRITTEN_REQUEST_URI:$1]
or
RewriteRule ^(.+)$ frontcontroller.php?Rewritten_request_uri=$1 [QSA]

Then adjust your frontcontroller.php to get the info from PATH_INFO or
QUERY_STRING.

The first one might require setting AllowPathInfo On in httpd.conf.

Joshua.

---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
   "   from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org