$_GET variables empty .htaccess rewrite

.htaccessapache-2.2

Given the URL

https://example.com/api/test/512/31

I want to rewrite to:

https://example.com/api/test.php?param1=512&param2=31

I've tried:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php?param1=$1&param2=$2 [QSA,L]

The rewrite works but $1 and $2 are empty. Any idea why?

Best Answer

RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php?param1=$1&param2=$2 [QSA,L]

How do you think $1 and $2 get set? You've not created any capturing groups in the RewriteRule pattern (which is a negated pattern so can't "match" anything anyway), so the $1 and $2 backreferences will indeed always be empty.

Since you are using extensionless URLs that map directly to files you also need to make sure that MultiViews is disabled (if not already). If MultiViews is enabled then you'd get the same result - no URL parameters - since mod_negotiation would have issued an internal subrequest for the file before mod_rewrite.

UPDATE:

Criteria (from comments):

  • Your .htaccess file is in the /api subdirectory.
  • /api/<something> always maps to /api/<something>.php. <something> can consist of an arbitrary number of path segments, eg. different/anothersubfolder/filename.
  • The /512/31 path segments at the end of the URL can consist of digits and letters. There are always two path segments, ie. /#1/#2.

Try the following instead:

Options -MultiViews

RewriteEngine On

RewriteCond %{DOCUMENT_ROOT}/api/$1.php -f
RewriteRule ^(.+)/(\w+)/(\w+)$ $1.php?param1=$2&param2=$3 [QSA,L]

The shorthand character class \w matches a-z, A-Z, 0-9 and _ (underscore). So that covers the "numbers and letters".