rewrite rule for an URL with 2 queries

Viewed 32

My URL looks like this:

example.com/index.php?f=directory&s=page

I want it to be like this instead:

example.com/directory/page

my rewrite rules look like this right now:

RewriteRule ^([A-Za-z0-9]+).html$ https://www.example.net/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/?(.*?)/?$ index.php?s=$1 [L]

it appears to work but not quite because if I call the queries in PHP I get something like this:

print $_GET['f'] */ it prints nothing
print $_GET['s'] */ it prints directory/page

which is not what I intend. How can I fix it?

Thank you.

1 Answers
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/?(.*?)/?$ index.php?s=$1 [L]

Do it like this instead:

RewriteRule ^([^/]+)/([^/]+)$ index.php?f=$1&s=$2 [L]

Request /directory/page and it internally rewrites the request to index.php?f=directory&s=page.

By making the regex more specific, the filesystem checks can probably be avoided.

To redirect from index.php?f=directory&s=page to /directory/page (if these URLs have already been indexed and/or linked to by third parties), then add the following redirect before the above directive:

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^f=([^&]+)&s=([^&]+)$
RewriteRule ^index\.php$ /%1/%2 [R=301,L]

But you must already be linking to the canonical /directory/page URL in your application.

Test with 302s to avoid potential caching issues. Clear your browser cache before testing.


RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/?(.*?)/?$ index.php?s=$1 [L]

You are only assigning a single URL parameter s, so yes, $_GET['f'] will indeed be empty.

Related