1

Im trying to rewrite url from long to short but cant wrap my head around this.

My survey rewrite works wonderfully but after completing my survet php redirects to www.example.com/survey_thank_you.php?survey_id=1 but I would like to show url like www.example.com/thank_you

Im not even sure if this is possible.

Im new with .htaccess and i have tried almost everthing

.htaccess

Options +FollowSymLinks Options -MultiViews RewriteEngine on RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] RewriteRule ^survey_thank_you.php?survey_name=([0-9a-zA-Z]+)/?$ Thank_you [L,NC,QSA] RewriteRule ^([0-9a-zA-Z]+)/?$ survey_form.php?survey_name=$1 [L,NC,QSA] #works like charm. 

Any help or directions will be highly appreciated.

Solution:

Options +FollowSymLinks Options -MultiViews RewriteEngine on RewriteCond %{ENV:REDIRECT_STATUS} ^$ RewriteCond %{QUERY_STRING} ^survey_id=([0-9a-zA-Z]+)/?$ RewriteRule ^survey_thank_you\.php$ /%1/thank_you [R,L,QSD] RewriteRule ^([0-9a-zA-Z]+)/thank_you$ survey_thank_you.php?survey_id=$1 [L,NC,QSA] RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] RewriteRule ^([0-9a-zA-Z]+)/?$ survey_form.php?survey_name=$1 [L,NC,QSA] 
1
  • RewriteRule matches against the path component of the URL only. If you want to check on specific query string contents, then you need to use a RewriteCond for that. Commented Mar 17, 2022 at 11:24

1 Answer 1

1

but after completing my survet php redirects to www.example.com/survey_thank_you.php?survey_id=1

You need to "correct" the URL that PHP is redirecting you to after the survey. If the desired URL is /thank_you (or /Thank_you?) then PHP should be redirecting to that URL.

You then use mod_rewrite in .htaccess to internally rewrite /thank_you back into the URL that your application understands. ie. /survey_thank_you.php?survey_id=1. However, therein lies another problem, where does the 1 (survey_id) come from in the query string? Presumably you don't want to hardcode this? So this would need to passed in the requested URL. eg. /1/thank_you or perhaps /thank_you/1?

However, is this really necessary? The resulting "thank you" page is not a page that should be indexed or a page that is normally navigated to by the user, so implementing a user-friendly URL here doesn't seem to be a worthwhile exercise?

RewriteRule ^survey_thank_you.php?survey_name=([0-9a-zA-Z]+)/?$ Thank_you [L,NC,QSA] RewriteRule ^([0-9a-zA-Z]+)/?$ survey_form.php?survey_name=$1 [L,NC,QSA] #works like charm. 

You are using a survey_name URL parameter (referencing an alphanumeric value) in your directives, but a survey_id ("numeric"?) URL parameter in your earlier example? So, which is it? Or are these rules unrelated?

You state that the second rule "works like charm", but how? What URL are you requesting? That would seem to rewrite /Thank_you to survey_form.php?survey_name=Thank_you - but that does not look correct?

As mentioned in comments, the RewriteRule pattern matches against the URL-path only. To match against the query string you need an additional condition that matches against the QUERY_STRING server variable. This would also need to be an external 3xx redirect, not an internal rewrite (in order to change the URL that the user sees). Therein lies another problem... if you don't change the URL that your PHP script is redirecting to then users will experience two redirects after submitting the form.

You also need to be careful to avoid a redirect loop, since you are internally rewriting the request in the opposite direction. You need to prevent the redirect being triggered after the request is rewritten. ie. Only redirect direct requests from the user should be redirected.

So, to answer your specific question, it should be rewritten something like this instead:

RewriteCond %{ENV:REDIRECT_STATUS} ^$ RewriteCond %{QUERY_STRING} ^survey_name=[0-9a-zA-Z]+/?$ RewriteRule ^survey_thank_you\.php$ /Thank_you [QSD,R,L] 

The check against the REDIRECT_STATUS environment variable ensures that only direct requests are processed, not internally rewritten requests by the later rewrite. REDIRECT_STATUS is empty on the initial request and set to the string 200 (as in 200 OK status) after the first successful rewrite.

The QSD flag (Apache 2.4) is necessary to discard the original query string from the redirect response.

So the above would redirect /survey_thank_you.php?survey_name=<something> to /Thank_you.

But this is losing the "survey_name" (or survey_id?), so should perhaps be more like the following, in order to preserve the "survey_name":

RewriteCond %{ENV:REDIRECT_STATUS} ^$ RewriteCond %{QUERY_STRING} ^survey_name=([0-9a-zA-Z]+)/?$ RewriteRule ^survey_thank_you\.php$ /%1/Thank_you [QSD,R,L] 

Where %1 is a backreference to the value of the survey_name URL parameter captured in the preceding CondPattern.

However, you would then need to modify your rewrite that turns this back into an understandable URL.

(But you should probably not be doing this in the first place without first changing the actual URLs in the application.)

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for really inclusive answer. These rules are not related. I did not realise i have to seperate these rules. Your both options works for what i was asking.
@Mikael You're welcome. I've updated my answer as the rule to redirect wasn't quite correct as written (in order to remove the query string and prevent a redirect loop as I had described!). I've also added some more explanation.
I've updated my question bit more where you can see how you helped me find the solution. Thanks alot!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.