Is there a way to have the mod_rewrite rules in my .htaccess
file take effect before PHP behind fcgi sees the request?
I have an email validation link that I want to redirect from root to the login page before PHP marks it in the database as confirmed.
These are the rules I have in my .htaccess
, and they work, but PHP sees the request before the rewrite rule takes effect.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{QUERY_STRING} activation_key=
RewriteRule ^$ /login [R,L]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
When PHP sees a request that contains the activation_key
query string, it marks the user as activated. If the user is already activated, the page will show an "Unknown validation link" error.
With these rewrite rules the request redirects to the /login
page and displays the error, indicating - I assume - that PHP had already seen the request.
This is the mod_fastcgi config:
<IfModule mod_fastcgi.c>
DirectoryIndex index.html index.shtml index.cgi index.php
AddHandler php5-fcgi .php
Action php5-fcgi /php5-fcgi
Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization
</IfModule>
If I'm understanding this correctly:
/?activation_key=foobar
and Apache sends back a response to redirect you to/login
./login
and that page says it has already seen the validation link. But there is noactivation_key
in this request, it only existed in the first request. It has probably seen the empty string before and that's why it's throwing an error now. (The exact logic in your PHP script may not match this explanation but I suspect it's something similar.)Try changing your rewrite rules like this:
That captures the activation key and passes it along on the next request to
/login
so that PHP will then have the key.It might be worth while you're debugging to echo out or log to a file the query string or the whole request or even the whole
$_SERVER
super global.Your last rewrite rule has an extra
/
in it that doesn't need to be there. This would be a better rule:.htaccess
files and the associatedAllowOverride all
directive carry a performance penalty with them. This becomes painfully obvious when usingstrace
and watching all the file operations looking for all the places a.htaccess
file could be hiding. If you're running your own Apache server rather than being on shared hosting, you might as well put these rules in the main config and setAllowOverride
to none. Inside a<Directory>
block they will work as they are. Anywhere else they will need an extra leading slash.