50

This is the .htaccess code for permalinks in WordPress. I don't understand how this works. Can someone explain?

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

I googled and found out that -f and -d part means to give real directories and files higher priority.

But then what are ^index\.php$ - [L] and RewriteRule . /index.php [L] ?

How does WordPress process categories, tags, pages, and etc. with just this?

Does it happen internally? If so, I'm interested in learning how to do it in PHP.

Thanks

1 Answer 1

65

^index\.php$ - [L] prevents requests for index.php from being rewritten, to avoid an unnecessary file system check. If the request is for index.php the directive does nothing - and stops processing rules [L].

This block is all one rule, and it says that if it is not a real file and not a real directory, reroute the request to index.php.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

index.php itself interprets the URL that was requested by the client (PHP can see the requested URL using $_SERVER['REQUEST_URI']) and it calls the correct code for rendering the page the user requested.

11
  • I noticed that wordpress redirects domain.com/index.php to domain.com. If I wanted to do something like that in PHP, should I just use the header function? I'm wondering is there's a better way (search engine friendly? more efficient?) to do it.
    – webnat0
    Commented Feb 21, 2011 at 3:26
  • I don't see any reason a 301 redirect from the Header function wouldn't be appropriate. You could tweak your mod_rewrite settings to do a quick 301 redirect in theory, but it isn't going to make a huge difference either way. Commented Feb 21, 2011 at 3:35
  • 2
    RewriteRule ^index\.php$ - [L]: isn't it redundant, since index.php is indeed a real file (thus hitting RewriteCond %{REQUEST_FILENAME} !-f)?
    – matpop
    Commented Dec 5, 2013 at 9:38
  • 1
    That's what I'm saying. When at first RewriteRule . /index.php [L] is executed, don't we get an existing filename? If so, wouldn't then RewriteCond %{REQUEST_FILENAME} !-f return false in the second iteration? I don't see an infinite loop fix, at best an optimization. What am I missing? Thanks for your help
    – matpop
    Commented Dec 5, 2013 at 21:45
  • 1
    @matpop I agree with you. Since index.php is a real file and it exists in the root, what is the need for RewriteRule ^index\.php$ - [L] to avoid internal loops? I agree there won't be a loop, I tested and haven't noticed a problem. For a billion $ company like wordpress should not have this simple mistake, I landed on this question just to look for an answer for this, anyone catches something we are missing?
    – Tarik
    Commented Dec 18, 2015 at 16:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.