skip to Main Content

I have already rewritten my old “ugly” URL:

http://example.com/ppd-brands/generic/?gen_id=Mjky

to

http://example.com/ppd-brands/generic/gen_id/Mjky

using the code below

RewriteRule ^ppd-brands/generic/gen_id/([^/]*)$ /ppd-brands/generic/?gen_id=$1 [L]

and it’s working.

Now my problem is how can I redirect the old “ugly” URL to the new URL when the user visits the old “ugly” URL?

2

Answers


  1. Redirect 301 /oldurl.htm /newurl.htm
    

    change old and new URL according to your need. Hope it helps you

    Login or Signup to reply.
  2. RewriteRule ^ppd-brands/generic/gen_id/([^/]*)$ /ppd-brands/generic/?gen_id=$1 [L]
    

    Just a precursor… whilst your old “ugly” URL was of the form /ppd-brands/generic/?gen_id=Mjky, you should ideally be rewriting to the actual file that handles the request, eg. index.php, instead of allowing mod_dir to issue an additional internal subrequest to the directory index – which is what I assume is happening here.

    For example:

    RewriteRule ^ppd-brands/generic/gen_id/([^/]*)$ /ppd-brands/generic/index.php?gen_id=$1 [L]
    

    Now, your main question… to externally redirect from the old “ugly” URL to the new URL. In this case, you need to be careful of a redirect loop, since if we simply redirect then the above rewrite will rewrite it back again in an endless loop. You can’t use a mod_alias Redirect (as the other answer suggests) for this reason. (And a mod_alias Redirect can’t match the query string either – another reason.)

    Aside: Since we changed the above rewrite to include index.php in the rewritten URL, which would appear to differ from the old “ugly” URL, we could perhaps get away with a simple redirect if you are on Apache 2.4 (but Apache 2.2 would result in a conflict because mod_dir would issue an internal subrequest for index.php before we can process the URL with mod_rewrite).

    We need to only redirect initial requests, not requests that we have already rewritten. We can do this by checking against the REDIRECT_STATUS environment variable, which is empty on the initial request and set to “200” (as in 200 OK HTTP status) after the first successful rewrite. (Another way is to check against THE_REQUEST, instead of the dynamic/rewritable URL-path.)

    For example, try the following before your existing rewrite:

    # Redirect "old" to "new"
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteCond %{QUERY_STRING} ^gen_id=([^/&]*)
    RewriteRule ^(ppd-brands/generic)/(?:index.php)?$ /$1/gen_id/%1 [QSD,R=302,L]
    

    Note that in order to match the query string we need a condition (RewriteCond directive) that checks against the QUERY_STRING server variable. The URL-path matched by the RewriteRule pattern notably excludes the query string.

    The index.php in the request URL is optional, so it matches /ppd-brands/generic/?gen_id=Mjky or /ppd-brands/generic/index.php?gen_id=Mjky (if that is the actual URL).

    The $1 backreference is simply to save typing/duplication. This will always contain ppd-brands/generic when the directive matches. We could have done the same with “gen_id”, but that could make the susbstitution string look a bit too cryptic.

    The %1 backreference (note the % prefix) is a backreference to the captured group in the last matched CondPattern (as opposed to $1 which refers to the RewriteRule pattern), ie. the value of the gen_id URL parameter.

    The QSD flag (Apache 2.4+) strips the query string from the redirected URL. Otherwise gen_id=XYZ would be passed through to the target URL. If you are still on Apache 2.2 then you would need to append a ? to the end of the substitution string instead (essentially an empty query string). eg. /$1/gen_id/%1?

    The “magic” is really the first condition that checks the REDIRECT_STATUS env var. As mentioned above, this ensures that we only process initial requests and not the rewritten request, thus avoiding redirect loop.

    Note that this is currently a 302 (temporary) redirect. Only change to a 301 (permanent) once you have tested this works OK. 301s are cached persistently by the browser so can make testing problematic.

    And just to clarify… a redirect like this should only be implemented once you have already changed all the URLs in your application. This redirect is to simply redirect search engines, backlinks and anyone who should manually type the URL (unlikely).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search