2

I'm using a htaccess file in my server but it's returing a "Not Found" error.

The code I'm using is:

Options -MultiViews
DirectoryIndex menu.php

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^/?$                            menu.php [NC,L,QSA]
RewriteRule ^/([\w-]+)/?$                   results.php?type=$1 [NC,L,QSA]
RewriteRule ^/([\w-]+)/([0-9]+)/?$          results.php?type=$1&id=$2 [NC,L,QSA]
RewriteRule ^read/([\w-]+)/([0-9]+)/?$      read.php?title=$1&id=$2 [NC,L,QSA]

Which is placed inside of the articles directory.

But when I visit localhost/articles/news I get the error. Any ideas where I'm going wrong?

1
RewriteRule ^/?$                            menu.php [NC,L,QSA]
RewriteRule ^/([\w-]+)/?$                   results.php?type=$1 [NC,L,QSA]
RewriteRule ^/([\w-]+)/([0-9]+)/?$          results.php?type=$1&id=$2 [NC,L,QSA]
RewriteRule ^read/([\w-]+)/([0-9]+)/?$      read.php?title=$1&id=$2 [NC,L,QSA]

None of the RewriteRule patterns (above) will match a request for /articles/news - so yes, you will likely get a 404. In per-directory .htaccess files the RewriteRule pattern matches the URL-path less the directory-prefix, so the URL-path that is matched does not start with a slash.

I assume this should be routed to results.php?type=$1 (the second rule)?

However, also note that RewriteCond directives only apply to the first RewriteRule directive that follows, not all of them, which you seem to be expecting. So, you either need to repeat the RewriteCond directives for each rule, or negate the condition and have a single exception at the top. In other words, instead of only applying the RewriteRule when the file does not exist. Abort the rewriting process when it does.

So, try the following instead:

RewriteEngine On

# Get out clause... if the request maps to a file or directory then abort
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]

# Request does not map to a file or directory...
RewriteRule ^/?$                           menu.php [L]
RewriteRule ^([\w-]+)/?$                   results.php?type=$1 [L,QSA]
RewriteRule ^([\w-]+)/([0-9]+)/?$          results.php?type=$1&id=$2 [L,QSA]
RewriteRule ^read/([\w-]+)/([0-9]+)/?$     read.php?title=$1&id=$2 [NC,L,QSA]

The NC (NOCASE) flag on the first 3 rules is not required (since the patterns are already case-insensitive). I'd also question whether you need the NC flag on the last rule as well (potential duplicate content issue if it is included)? The QSA flag is not required on the first rule, since the query string will be appended by default, given that a query string is absent from the substitution.

Since you have the DirectoryIndex set, the first rule might not be required anyway?

| improve this answer | |
  • Did you manage to get anywhere with this? – MrWhite Sep 15 '16 at 22:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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