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 Answer 1

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?

1
  • Did you manage to get anywhere with this?
    – MrWhite
    Commented Sep 15, 2016 at 22:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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