user1610904
user1610904

Reputation: 397

Htaccess - Rewrite and Redirect URL with PHP GET variable

I am trying to both rewrite and redirect this URL:

https://www.domain.com/video-lessons-page.php?item=stocks

to go to this URL:

https://www.domain.com/stocks-video-lessons

Here is the code I'm currently working with:

RewriteCond %{QUERY_STRING} ^item=([^&]+)
RewriteRule ^/?video-lessons-page\.php$ https://www.domain.com/%1-video-lessons? [R=301,L]
RewriteRule ^(stocks|finance|accounting)-video-lessons$ video-lessons-page.php?item=$1 [NC,L]

Unfortunately with the above code I'm having issues. The first two lines work great by themselves in that it redirects /video-lessons-page.php?item=stocks to /stocks-video-lessons.

And the third line also works great by itself to where the /stocks-video-lessons URL functions correctly with the GET variable and the page's code.

But putting them together is problematic. Right now I'm getting errors like "www.domain.com redirected you too many times." etc. Any ideas?

Upvotes: 2

Views: 1266

Answers (2)

MrWhite
MrWhite

Reputation: 45829

Just to clarify, presumably you have already changed all your internal URLs to the form /stocks-video-lessons and the reason for the external redirect is because the "ugly" URLs have already been indexed and linked externally?


As you have found, you are getting a redirect loop because these two rules conflict and it's constantly redirecting/rewriting from one to the other.

You need to redirect when only the initial request contains the URL /video-lessons-page.php, not the rewritten URL (which is what's happening here). You can check the initial request by checking against THE_REQUEST server variable (which contains the full HTTP request as sent by the browser).

Something like the following:

RewriteCond %{THE_REQUEST} /video-lessons-page\.php?item=(\w+)
RewriteRule ^video-lessons-page\.php$ https://www.example.com/%1-video-lessons? [R=301,L]

RewriteRule ^(stocks|finance|accounting)-video-lessons$ video-lessons-page.php?item=$1 [L]

Note you must clear your browser cache before testing, since 301 (permanent) redirects will be cached by the browser. (Often easier to test with 302 redirects.) Only use the NC flag if you specifically need a case-insensitive match.

UPDATE: I've changed the regex on the query string parameter value, from ([^&]+) to the slightly more restrictive (\w+). \w being the shorthand character class for a word character (which naturally excludes & and crucially spaces). Since THE_REQUEST contains a string of the form:

GET /video-lessons-page.php?item=stocks HTTP/1.1

...we need to stop capturing before the space. The previous pattern ([^&]+) would have captured everything to the end of the string ie. "stocks HTTP/1.1". So, I would have expected a 404, since an invalid redirect would have occurred but the internal rewrite would have failed. (?)

Upvotes: 1

user1610904
user1610904

Reputation: 397

Thanks to w3dk's guidance, I figured it out, just needed a QUERY_STRING to stay in place in addition to the THE_REQUEST.

Final code:

RewriteCond %{THE_REQUEST} video-lessons-page\.php
RewriteCond %{QUERY_STRING} ^item=([^&]+)
RewriteRule ^video-lessons-page\.php$ https://www.example.com/%1-video-lessons? [R=301,L]
RewriteRule ^(stocks|finance|accounting)-video-lessons$ video-lessons-page.php?item=$1 [L]

Upvotes: 0

Related Questions