Understanding Wordpress' redirects

How does Wordpress to redirect access to a database content from URLs given by users?

Wordpress includes on each hosting an .htaccess file with an URL-trwritting code that replaces dynamic URLs to static URLs, where the webmaster or blogger choose this option, that is done by the server, but it does more than that.

The .htaccess code

# BEGIN WordPress
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Here is what he means in detail ...

# BEGIN WordPress
# END WordPress

Simple comments indicating the beginning and end of URLs rewriting code.

<IfModule mod_rewrite.c>
</IfModule>

Conditional expression: the code included between these two tags is executed only if the URL rewritting is permitted by the host and in this case the mod_rewrite module must be available.

RewriteEngine On 

Active the URLs rewritting engine.

RewriteBase / 

Explicitly states that the site's root is "/", which is not the default for most Unix based hostings where the files are adressed on the file system, something like /home/user/www/.

This directive introduces a difference between PHP and the server: for PHP, the root is the directory location and the webmaster must use php variables to find the root of the site (see the script Bioloide for a practical application).

Once the base is well defined, we can use in the pages relative addresses like /mypage.html.

RewriteCond %{REQUEST_FILENAME} !-f

A precondition for the directive to follow.

It prevents automatic redirection to index.php, which is the default.

REQUEST_FILENAME is an Apache variable that represents the actual path in the filesystem on the server.

%{} This code is the way for Apache to designate a variable.

! this symbol negate the pattern that follows.

-f specifies that it is a file and !-f excludes a file.

-d specifies that it is a directory and !-d excludes a directory.

So the condition excludes URL matching a real files on the website, while:

RewriteCond %{REQUEST_FILENAME} !-d

excludes a subdirectory..

RewriteRule . /index.php [L]

RewriteRule command asks to replace the regular expression, in this case one point, with the /index.php address.

The point representing any character or character sequence, any URL is redirected to index.php (but if it is a real file or directory).

[] Adds a rule to the server.
L means Last,the rule is the last to be applied.

The whole rule so redirects any URL to /index.php but if it matches a real file or directory.

Explanation of operations

By default, all access are redirected to index.php when there are not real files. But index.php is not really a page, it's a script that searches for posts in the database.

The URL of a page or file located on the site and not run by Wordpress, as document.html or archive.zip or image.jpg, are served directly.

When dynamic URLs are the option, in the form http://www.scriptol.fr/index.php?p=n, the script looks in the database to a record corresponding to the ID in parameter and build a page with the template.

It is recommended to have static URLs made of keywords and preferably with an identifier added. This is done in the permalinks options with something like:

/%postname%-%post_id%  

Pretty URLs as http://www.scriptol.fr/my-post-12345 are redirected to index.php.
But the "my-post-12345" is retrieved in the database that stores the URL when creating the post (and built from the title), then the software incorporates the content corresponding to compose a page.

New rule

The latest version of the htaccess file includes an additional rule:

RewriteRule ^index\.php$ - [L]  
This prevents / and /index.php for a sub-directory to be treated as the same URL and it speeds up the scripts.

The 404 page

It is also run by the software: if the index.php script does not found the requested URL, it loads a special page, 404.php, which is included in the theme.

If you want to improve error handling of URLs by users, it is better to change the file 404.php rather than .htaccess.
See for example the article: A smart 404 page.

External Links