Reputation: 46463
With this .htaccess
:
RewriteEngine On
RewriteRule foo/(.*) /foo-$1 # here I tried [L], [PT], [C], etc.
RewriteRule . index.php [L]
I've tried all possible flags for the first RewriteRule, but always, this PHP code:
<?php echo $_SERVER['REQUEST_URI']; ?>
always echoes /foo/bar
instead of /foo-bar
, when accessing http://example.com/foo/bar. Why?
How to have Apache's RewriteEngine also modify the REQUEST_URI
that will be seen by PHP?
Note: I don't want [R] because a redirection would generate a new browser request, and change the URL displayed in the URL bar, which I don't want.
Upvotes: 4
Views: 2025
Reputation: 4467
PHP's $_SERVER['REQUEST_URI']
returns the Apache original-uri
and not current-uri
.
With this .htaccess
file:
CGIVar REQUEST_URI current-uri
RewriteRule (.*) index.php [L]
then a request to example.com/hello/world
will give:
$_SERVER["REQUEST_URI"] "/index.php"
$_SERVER["REDIRECT_URL"] "/hello/world"
Without the CGIVar
line, it would give "/hello/world" for both REQUEST_URI
and REDIRECT_URL
.
Upvotes: 1
Reputation: 2512
I think what you try to do is impossible without some work around. I have provided 2 solutions in this post, one using auto_prepend_file and one using mod_proxy.
Please look at the script below, this does not directly set the REQUEST_URI global, but instead it overwrites it in PHP, with the following code:
php_value auto_prepend_file "before.php"
RewriteEngine On
RewriteRule foo/(.*) /foo-$1
RewriteRule . index.php [L]
Make sure to add this line:
php_value auto_prepend_file "before.php"
In this script you can replace the REQUEST_URI:
Like:
$_SERVER['REQUEST_URI'] = "/" . str_replace('/', '-', ltrim($_SERVER['REQUEST_URI'], "/"));
You can further improve this script, but I think the concept is clear.
Index.php is unaffected but contains the rewritten rule:
var_dump($_SERVER['REQUEST_URI']); //string(7) "/foo-bar"
A request to http://localhost/foo/bar?test
is now: string(13) "/foo-bar?test"
When using [L], you can obtain the rewritten url by:
var_dump($_SERVER['REDIRECT_URL']); # /foo-bar
So the .htaccess becomes:
php_value auto_prepend_file "before.php"
RewriteEngine On
RewriteRule foo/(.*) /foo-$1 [L] # please note [L] here
RewriteRule . index.php [L]
Thus the before.php can be replaced by:
$_SERVER['REQUEST_URI'] = $_SERVER['REDIRECT_URL'];
Found out you can also use mod proxy:
I had to enable the following modules:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
Now your .htaccess is changed to (notice the [P] flag):
RewriteEngine On
RewriteRule ^foo/(.+)$ /foo-$1 [L,P]
RewriteRule . index.php
This will proxy all foo/bar requests to /foo-bar and change the $_SERVER['REQUEST_URI']
accordingly.
var_dump($_SERVER['REQUEST_URI']); //output: string(8) "/foo-bar"
I think using the PHP prepend file is a more efficient way though.
Upvotes: 3
Reputation: 46463
After further research, it seems that PHP will always see the original URL in $_SERVER['REQUEST_URI']
and not the target of the RewriteRule. (authoritative source needed here).
By the way, the target of a RewriteRule is usually a file that will process the request, except if we use a [R] redirection flag, then in this case the browser will do a new request to the new URL (and the browser URL bar changes).
Upvotes: 0