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.
See also RewriteRule when the substitution string is not a file path but an URL which should be processed by next rules.
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.
PHP's $_SERVER['REQUEST_URI'] returns the Apache original-uri and not current-uri.
CGIVar Directive
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With