mod_rewrite works within directory not on root

5,245

Solution 1

Various causes are possible here. It would be helpful to know more about your setup (folder layout, virtual host configuration and especially any other contents of your .htaccess files). Some things that come to my mind:

As Eric Brandel points out, mod_rewrite will apply all rules present in your .htaccess file (or server config) one by one unless [L] is used to stop processing. The rewritten URL could thus become changed again by subsequent RewriteRules (are there any?) in your .htaccess file before the page is finally being rendered. If this is the case, using [L] at the end of all three lines should be enough to solve your problem.

In situations where folders of different subdomains are placed inside of each other, you might need to tell mod_rewrite explicity that the current path is on root level, or the rules will not trigger:

RewriteBase /

If this doesn't help I would recommend to check if mod_rewrite triggers at all, e.g. by using a very simple redirect rule like this one:

RewriteRule .* /?hello [R,L]

Reason: It might even be possible that the rendering of tags.php is not due to mod_rewrite, but to apache automatically adding the extension .php when /tags is called (see here). You might need to use RewriteEngine On to turn mod_rewrite on, since has to be activated individually for each virtual host. Maybe it is not yet active on your subdomain.

If you are not sure which rule is being triggered currently, you could try to find out by e.g. turning rules temporarily into a redirect instead of a rewrite:

RewriteEngine On
RewriteBase /
RewriteRule ^tags/(\w+)/(\d+)/?$  tags.php?tag_name=$1&tag_id=$2 [R,L]
RewriteRule ^tags/(\w+)/?$ tags.php?tag_name=$1 [R,L]
RewriteRule ^tags/?$ tags.php?tag_name= [R,L]

Edit: Maybe this prevents the server from triggering the rule if the script goes by the the same name, so you can keep "tags" as the folder name:

Options -Multiviews

(see https://stackoverflow.com/questions/444592/mod-rewrite-rules-and-content-negotiation for another example)

Solution 2

With .htaccess, if a request matches multiple rules, it will utilize the last one found, unless you tell it to stop processing. You can do that with adding [PT,L] to the end of each line.

# Rewrite rule for tags
RewriteRule ^tags/(\w+)/(\d+)/?$ restAPI.php?type=tags&tag_name=$1&tag_id=$2  [PT,L]
RewriteRule ^tags/(\w+)/?$ restAPI.php?type=tags&tag_name=$1 [PT,L]
RewriteRule ^tags/?$ restAPI.php?type=tags&tag_name= [PT,L]

PT Flag: http://httpd.apache.org/docs/current/rewrite/flags.html#flag_pt

L Flag: http://httpd.apache.org/docs/current/rewrite/flags.html#flag_l

I believe [PT,L] may be overkill, but I've seen it used a lot. It adds clarity, in my opinion. Using [PT] alone may work.

Solution 3

I found my way through my issue. As suggested by Eric Brandel I just made a rule with hard coded values for tag_name and tag_id as

RewriteRule ^test/(\w+)/(\d+)/?$  tags.php?tag_name=extra&tag_id=4

And I was able to get my Query parameters then I changes my RewriteRules to

# Rewrite rule for tags
RewriteRule ^tag/(\w+)/(\d+)/?$  tags.php?tag_name=$1&tag_id=$2 [L]
RewriteRule ^tag/(\w+)/?$ tags.php?tag_name=$1    [L]
RewriteRule ^tag/?$ tags.php?tag_name= [L]

changing tags/ to tag/ in the URI to match and my problem was solved. I started getting all the query parameters to tags.php.
So, It seems I had the trouble of content negotition as suggested by schwarzbrot
Thanks to Eric Brandel, schwarzbrot and w3d for their valuable feedback to solve this long troubling issue.

Share:
5,245

Related videos on Youtube

Anvesh Saxena
Author by

Anvesh Saxena

Updated on September 18, 2022

Comments

  • Anvesh Saxena
    Anvesh Saxena over 1 year

    I am having a problem with my RewriteRule for the querystring portion. What I am able to debug is that the rule is being triggered at least because the page "tags.php" is being rendered but without the URL parameters. This .htaccess file with the rules is within the root folder for my sub-domain and has the following content:

    # Enable Rewriting  
    RewriteEngine on  
    
    # Rewrite rule for tags
    RewriteRule ^tags/(\w+)/(\d+)/?$ tags.php/?tag_name=$1&tag_id=$2 [L]
    RewriteRule ^tags/(\w+)/?$ tags.php?tag_name=$1    [L]
    RewriteRule ^tags/?$ tags.php?tag_name= [L]
    

    A similar .htaccess file exists for a directory within my sub domain which is working as expected with the necessary URL parameters also being available. The .htaccess file within the directory reads as follows:

    # Rewrite rule for tags
    RewriteRule ^tags/(\w+)/(\d+)/?$ restAPI.php?type=tags&tag_name=$1&tag_id=$2     
    RewriteRule ^tags/(\w+)/?$ restAPI.php?type=tags&tag_name=$1    
    RewriteRule ^tags/?$ restAPI.php?type=tags&tag_name=
    

    Can anyone see a problem with my RewriteRules? I am also facing an Internal Server Error sometimes which I am second guessing is due to the same problem.

    I have Apache version 2.2.23 on my shared hosting.

    Update

    I have following folder structure
    /sub-domain root
    |-- .htaccess
    |-- tags.php
    |-- article.php
    |-- index.php
    |-- folders for Images and JavaScript

    As suggested by schwarzbrot I also tried changing the rewrite rule associated with 'tags.php' but to my surprise linking it to files which didn't even exist didn't give me any error.

    • MrWhite
      MrWhite over 11 years
      Is tag_name available to your server-side script? If using PHP, does $_GET['tag_name'] exist? This is presumably the only code that directs a request to tags.php?
    • Anvesh Saxena
      Anvesh Saxena over 11 years
      @w3d tag_name is not available to my server-side script for tags.php. And thanks for correcting my question
  • Anvesh Saxena
    Anvesh Saxena over 11 years
    Thanks for your suggestion but I am still stuck with the same problem, absence of the query parameters to tags.php
  • MrWhite
    MrWhite over 11 years
    "Using [PT] alone may work." - I would have said this was probably the other way round... if tags.php is a valid file path then only [L] would be required IMO.
  • MrWhite
    MrWhite over 11 years
    Just to note, the R in this case will result in a 302 external redirect. The OP appears to require an internal rewrite.
  • Anvesh Saxena
    Anvesh Saxena over 11 years
    Thanks for your idea.. had problem with Content Negotiation you suggested