Grow your CSS skills. Land your dream job.

301 Redirect Problem

  • # January 11, 2011 at 1:22 pm

    I’m currently migrating my website to WordPress and as a result the URLs of some of my pages are changing. So I’m using PHP headers to redirect like this:

    < ?
    Header( "HTTP/1.1 301 Moved Permanently" );
    Header( "Location: http://www.mysite.com/page-1/" );
    ?>

    The old url would be http://www.mysite.com/page-1.php. The problem is that I am ending up in an infinite redirect loop. /page-1.php redirects to /page-1/ which for some reason just loads /page-1.php again. But if I delete page-1.php and try to go there I get a 404 not found… which means that I need a redirect there. What am I doing wrong?

    gno
    # January 11, 2011 at 1:38 pm

    If you are using mod_rewrite on apache, or similar on other web servers, you should check the configuration.

    It looks as if the web server makes the request /x/ turn into /x.php

    If wordpress works with the “good looking”-urls, a solution would be to name the pages on wordpress slightly different from your original ones. Like /page-1/ -> /page1/ to work around it.

    While I’m not into wordpress at all, I could imagine that they use the same kind of rewriting as I do.

    - check if requested file exists – e.g /css/stylesheet.css
    - if it does – return that file
    - otherwise – return some-bootstrap-file.php?url=…

    So, if your wordpress page is named the exact same as your old page, this would screw it up and be the cause of the infinite loop – and thus – our little workaround would work…

    # January 11, 2011 at 1:46 pm

    While that solution would work I’d rather not go that route if possible…

    My mod_rewrite rules look like this:


    # BEGIN WordPress

    RewriteEngine On
    RewriteBase /
    RewriteRule ^index.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]

    # END WordPress

    Does that look like its causing the problem? Is there any way I could modify it to make it work like I want? Sorry, I’m not very familiar with how mod_rewrite works.

    gno
    # January 12, 2011 at 2:42 am

    It does indeed look like my initial thoughts was correct.

    What the two RewriteCond lines is saying is basicly, only do this rewrite if the request is not for a file or directory. Translated to plain english:
    - Only apply following RewriteRule(s) if REQUEST_FILENAME is not a file
    - Only apply following RewriteRule(s) if REQUEST_FILENAME is not a directory
    (with REQUEST_FILENAME being the apache server variable it is)

    So, that is why your mypage-1.php file is accessible. And we need that functionality, to be able to link to stylesheets, javascript files or images.

    The RewriteRule syntax is like this: RewriteRule [RegexPattern] [RegexSubstitution] [flags]

    The [L] flag means “last”; the rewriting will only happen one time. If the first rule changes the request, the second rule wont be applied.

    The first RewriteRule means in plain english:
    - if the request starts with index.php, do nothing, and do not apply anymore rules

    symbol definitions:
    ^ means, starts with
    . is just a n escaped dot – because dots is a symbol used in regular expressions
    - (dash) means do nothing about this

    The second one means:
    - if the request is anything rewrite to /index.php, and do not apply anymore rules

    The second one shows why the dot was escaped in the first one.

    How does WordPress know what page you requested then, you might ask? Nothing is passed to the index.php file.

    Well, you could add the request to a _GET variable which would look something like this:

    RewriteRule ^(.*)$ index.php?url=$1

    But, that is not necessary – as the QUERY_STRING server variable is passed thru on default. (accessible through $_SERVER in PHP).

    Well, for your solution – how many pages do you have, that you want to redirect like that?

    One simple solution would be to add a line like this before the first RewriteRule;

    RewriteRule ^page-1 index.php [L]
    RewriteRule ^page-2 index.php [L]

    This would force the /page-1/ to go to index.php while /page-1.php would go to page-1.php. And the same with page-2.php ofc…

    I hope this was useful to you ;-)

    # January 13, 2011 at 1:49 pm

    Thanks for that, the explanation was especially helpful. The code you gave me didn’t quite work (I think because it also made page-1.php redirect to index.php, which gave a 404 error) but I was able to solve the problem by deleting the .php files and doing my redirects through mod_rewrite instead:


    RewriteRule ^page-1.php$ /page-1 [R=301,L]
    gno
    # January 13, 2011 at 8:14 pm

    I’m glad that it helped. I wrote most of the stuff free from memory, so that might be why it did not work out as I expected.

    Thus, your solution with exclusive mod_rewrite redirecting is much more elegant than the original php files doing the redirecting. :-)

Viewing 6 posts - 1 through 6 (of 6 total)

You must be logged in to reply to this topic.

*May or may not contain any actual "CSS" or "Tricks".