Mohamed Nuur Mohamed Nuur - 1 year ago 64
PHP Question

.htaccess and mod_rewrite - can't get it to work

I'm trying to use names as the url, like stackoverflow. I have a godaddy linux hosting and am using .htaccess to control the mod_rewrite url.

I'm trying to get the following:

  • /about => about.php

  • /schools/add => add-school.php

  • /api/questions/ask => /questions.php?action=ask

  • /api/questions/158 => /questions.php?action=get&id=158

  • /api/questions/144/points => /questions.php?action=get-points&id=144

This is what I have so far and it's not working:

## Mod rewrite manual:
<IfModule mod_rewrite.c>
RewriteEngine On

# try the corresponding php file
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ([A-Za-z0-9_-]+) $1.php [qsa]

# special cases
RewriteRule ^schools\/add$ add-school.php

RewriteRule ^api\/questions\/ask$ "api.php?action=ask" [qsa]
RewriteRule ^api\/questions\/(\d+)$ "api.php?action=get&id=$1" [qsa]
RewriteRule ^api\/questions\/(\d+)\/points$ "api.php?action=get-points&id=$1" [qsa]


Answer Source

There are few mistakes in your code:

  1. Rewrite rules ordering is very important. You should always order from most specific ones to most generic ones. Remember generic ones can match patterns of specific rules and override those special cases.
  2. Always mark individual end of rule with L (last).
  3. Forwarding requests to .php you need to make sure that php file actually exists.

With those suggestion here is your modified code:

Options +FollowSymLinks -MultiViews

<IfModule mod_rewrite.c>
  # Turn mod_rewrite on
  RewriteEngine On
  RewriteBase /

  # special cases
  RewriteRule ^schools/add/?$ /add-school.php [L,NC]

  # API
  RewriteRule ^api/questions/ask/?$ /api.php?action=ask [L,QSA,NC]
  RewriteRule ^api/questions/(d+)/points/?$ /api.php?action=get-points&id=$1 [L,QSA,NC]
  RewriteRule ^api/questions/(d+)/?$ /api.php?action=get&id=$1 [L,QSA,NC]

  # try the corresponding php file if it exists
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{DOCUMENT_ROOT}/$1.php -f
  RewriteRule ^(.+?)/?$ $1.php [L]