What do Rewritecond and Rewriterule mean in a . htaccess file?

Asked

Viewed 27,855 times

23

I know they are used for many purposes, either internal or external redirection, but I never understood what each one does, whenever I need something I have to resort to ready scripts because I do not know how to do.

For example, in this code:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?params=$1 [NC]

It redirects everything to my index and what is after as parameter, but what would mean the lines RewriteCond %{REQUEST_FILENAME} !-f and RewriteCond %{REQUEST_FILENAME} !-d?

2 answers

41


Rewritecond

You must use the directive RewriteCond to add conditions to apply or not redirect.

For example:

# Redirect when we have a single parameter
RewriteCond %{SCRIPT_FILENAME} !-f 
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_-]+)/$ index.php?mod=$1

In this case, the flags !-f and !-d are determining that the redirect will only occur if there is no file or folder with the corresponding url.

Syntax

The syntax of the command is:

RewriteCond TestString CondPattern

Where CondPattern is a REGEXP perl compatible, with a few additions.

You can prefix Pattern with ! to reverse its effect. There are some variations that allow using the CondPattern without REGEXP also:

'<CondPattern'
'>CondPattern'
'=CondPattern'

These last three treat the CondPattern literally as a string, and compare respectively to TestString with the literal value of CondPattern

See some more conditions:

  • -d Take the result of TestString and checks if it is an existing directory
  • -f Take the result of TestString and checks if it is an existing file
  • -s Does the same as the -f, but only considers non-empty files
  • -l Checks whether the result of TestString is path to a symbolic link
  • -x Checks whether the result of TestString is a path with +x permission
  • -F Equals to -f, but does a test to see if the file is really accessible by Apache. This implies making an extra internal request on the test, beware of overuse.
  • -U Even if the -F, but tests by URL and not Path

All these tests can be denied with a ! at first.

Variables

For both Rewritecond and Rewriterule, there are some pre-populated variables that can be used delimited with %{ }. See some of the most common:

  • REMOTE_ADDR is the IP of host remote

  • REQUEST_FILENAME is the complete file path that meets the original request, based on the filesystem machine, and not relative to hosting. Caution: if used in Virtualhost, has the same effect as the REQUEST_URI.

  • REQUEST_SCHEME returns usually http or https, depending on the connection.

  • REQUEST_URI is one of the most commonly used variables. It is the one that has the request path, for example index.html. Her nay includes the query. Everything that comes from ? is returned in QUERY_STRING.

  • THE_REQUEST is the full line of the request, for example GET /index.html HTTP/1.1. Does not include the headers and is not "escaped", unlike other variables.


Rewriterule

The Rewriterule directive rewrites the URL, and if it occurs more than once, it is applied in the sequential order of the file.

Syntax

 RewriteRule Pattern Substitution [flags]

Pattern is basically a Perl-compatible Regex. On the first occurrence, the Regex is applied to the URL after decoding (%). The following Regexes are applied to the output of the previous Rewrite.

Substitution is a string that can be merged with results (groups) extracted from Regex, and also variables delimited by %{ } as shown above.


Flags

Here are some of the most common flags:

  • L considers this to be the last Rewrite, no longer applying any rule that modifies the URL

  • R=code make a redirect with the specified code (ex: 301, 302)

  • NC (No-case) makes comparisons ignoring upper and lower case

  • N redoes the modification chain, starting with the first again

  • QSA(query string append) after the modifications made, applies the query string original at the end of the line (in other words, preserves what was after ? in the original URI)

  • CO arrow one cookie in format CO=NAME:VAL:domain[:lifetime[:path[:secure[:httponly]]]]

The full description of the flags can be found on documentation.

Example:

RewriteCond %{HTTP_HOST} ^www.(([a-z0-9_]+.)?exemplo.com.br)$ [NC]  
RewriteRule .? http://%1%{REQUEST_URI} [R=301,L,QSA]

In the example above we are checking if the domain is with www, and removing it on the next line, keeping the rest of the URL.

The R=301 flag determines it to be a permanent redirect, and the L indicates it is the last operation of this string. NC indicates that the comparison will ignore uppercase and lowercase, and the QSA will cause if any query string (?nome=valor&...), this is saved in redirect.

Describing the example set in the question

  • RewriteEngine On
    Activates the Rewrite module, which rewrites the URL.

  • RewriteCond %{REQUEST_FILENAME} !-f
    Determines that rewrite will only apply if (!) there is a file (-f) with that name

  • RewriteCond %{REQUEST_FILENAME} !-d
    Determines that rewrite will only apply if (!) there is a directory (-d) with that name

  • RewriteRule ^(.*)$ index.php?params=$1 [NC]
    Redirects the user to index.php? params=$1 for any URL entered.
    Here, the $1 is the first Regex group, determined by ( )s in catching.
    The NC in this case is useless, nor would it need to be in Rewrite.

  • The q would be a permanent redirect determined by the flag R=301?

  • 1

    You use 301 when it’s a definite thing, or 302 when it’s a temporary redirect. usually you don’t need to specify this manually.

  • http://answall.com/a/78445/70

9

Are guidelines for the module MOD_REWRITE.

http://httpd.apache.org/docs/2.2/pt-br/mod/mod_rewrite.html

As the httpd manual itself says:

Rewritecond: The directive Rewritecond sets a condition for a rule. One or more Rewritecond may precede a directive Rewriterule. The following rule is then used only if both the current state of the URI matches its default, and if these conditions have been met.

Rewriterule: The directive Rewriterule is the true flagship of rewriting. Directive can occur more than once, with each instance defining a single rewrite rule. The order in which these rules are defined is important - this is the order in which they will be applied at runtime.

A regular expression is used perl compatible. At first Rewriterule is applied to the (%-decoded) request URL; subsequent patterns are applied to the output of the last matching Rewriterule rule.

In the example

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?params=$1 [NC]

RewriteEngine On Informs to activate the Rewrite module

RewriteCond %{REQUEST_FILENAME} !-f Informs that a condition will be created to be applied to the requested file name. Exclamation is the negation sign and -f asks to verify the existence of a physical file. Therefore the translation is

CONDIÇÃO = SE ARQUIVO_REQUISITADO NÃO EXISTE FISICAMENTE

RewriteCond %{REQUEST_FILENAME} !-d Informs that a condition will be created to be applied to the requested file name. Again, the exclamation indicates negation and -d asks to check the existence of a directory physically. Therefore the translation is:

CONDIÇÃO = SE ARQUIVO_REQUISITADO NÃO EXISTE COMO DIRETÓRIO FISICAMENTE  

RewriteRule ^(.*)$ index.php?params=$1 [NC] Informs that a rewrite rule will be applied. ^(.*)$ Indicates to store all URL request in a variable (Circumflex indicates start and Dollar sign indicates end). index.php? params=$1 Indicates to replace the request by redirecting the flow to index.php and placing it entirely as a params parameter. * [NC]* These are flags. In the case indicates not to be sensitive to upper or lower case (NON-CASE).

More about flags here

  • Simple and direct explanation. Finally I understood.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.