David Passmore David Passmore - 4 months ago 11x
PHP Question

.htaccess 301 and PHP query string

I'm wondering if the wonderful world of the SO community can help me with this one.

I have the following URL's that I would like to redirect/rewrite in my


1. Redirect

I am trying to 301 redirect this URL:




I have attempted the following:

RewriteEngine On

RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+staff-view\.php\?i=([^\s]+) [NC]
RewriteRule ^ /staff-view/%1/? [R=301,L]

however when navigating to the from URL it does not redirect.

2. PHP Query String

I am using the below to rewrite:

RewriteRule ^staff-view/([^/]+)/?$ /staff-view.php?i=$1 [L,QSA,NC]

and accessing through URL


it correctly directs me to the right page, but when attempting to access
via the following methods:


They both are empty:

array(0) { } array(0) { }

I would appreciate any help, if you need any more info, please let me know.

Update 1


RewriteEngine On

RewriteRule ^staff/([^/]+)/?$ /staff-view.php?i=$1 [L,QSA,NC]

RewriteBase "/"

RewriteCond %{REQUEST_URI} ^staff-view\.php$
RewriteCond %{QUERY_STRING} ^i=([A-Z0-9_]*)$
RewriteRule ^(.*)$ ^staff/%1/

I have attempted to access the file from:


and it DOES NOT work. However, if I access the file from:



But if I go to
it does not redirect to
- this is not the end of the world, but I would like to fix it, but the deep directory issue as a priority


Trying to parse %{THE_REQUEST} (e.g., "GET /staff-view.php?i=account_id HTTP/1.1") to extract both the path and the query string could work but it's unnecessarily complex. I think it's much simpler to use two rewrite conditions that take advantage of the server variables %{REQUEST_URI} and %{QUERY_STRING} because they are pre-populated with the info you're interested in.

Try the following:

RewriteEngine On

#If you don't have this set in your htaccess, 
#  Apache may prepend the final path with your on disk dir structure
RewriteBase "/"

#Rewrite if the /staff-view.php page is requested
RewriteCond %{REQUEST_URI}  ^/staff-view\.php$

#Rewrite if the query string contains i parameter anywhere
#If account ID can be only digits, use [0-9] instead of [a-zA-Z0-9_]
RewriteCond %{QUERY_STRING} .*\bi=([a-zA-Z0-9_]+)\b

#Rewrite the account ID as part of the path. Append the query string
#  in order to preserve other query parameters (eg: if user asked for
#  /staff-view.php?i=123&x=boo, you want to preserve x=boo.  a 301
#  redirect tells the browser to go to the new path and to remember it
#This will stop processing and cause the browser to make a new request
RewriteRule ^(.*)$  staff-view/%1/ [QSA,R=301,L]

#Finally, we want to silently forward any request matching the last
#  redirect target to the actual file that will serve the request. Notice
#  that this has a filename different from the initial staff-view.php so
#  we don't end up in an endless redirect loop. The account ID should
#  be of the same format as above: ([a-zA-Z0-9_]+).  The [L] flag tells
#  the server to stop looking for new redirect instructions
RewriteRule ^staff-view/([a-zA-Z0-9_]+)/$ final.php?i=$1 [L,QSA]

The logic is easy to follow: If the path requested is /staff-view.php, and if the query string contains the i parameter, tell the user's browser to go instead to /staff-view/ID, preserving the other query params. Finally, when the browser asks for this new path, silently (without telling the browser) forward the request to final.php along with the ID and other query params