This assumes that p
, id
or catid
always appears at the start of the query string, and that the value of this parameter is the "file" basename in the new URL, as per your code examples.
RewriteEngine On
RewriteCond %{QUERY_STRING} ^(p|id|catid)=(\d+)
RewriteRule ^$ /%2.php? [R=301,L]
The ^$
pattern only processes requests for the document root (ie. example.com/
). The %2
back reference refers to the 2nd parenthesised sub pattern in the CondPattern (ie. (\d+)
). If you omit the R
flag (and don't specify an absolute URL) then it will result in an internal rewrite, not an external redirect as I would assume is required here (ie. the URL in the address bar would not change).
The ?
on the end of the RewriteRule
substitution strips the original query string from the rewritten URL. This essentially creates an "empty" query string (the ?
is not present in the result). Alternatively you can use the QSD
(Query String Discard) flag on Apache 2.4+
By default, unless you specify a new query string on the RewriteRule
substitution then the original query string will be copied onto the rewritten URL (as you have found). If you ever wanted to merge the original query string with a new one that you specify then you would need to use the QSA
(Query String Append) flag.