Skip to content

Instantly share code, notes, and snippets.

@yegnold
Last active December 19, 2015 05:09
Show Gist options
  • Save yegnold/5901983 to your computer and use it in GitHub Desktop.
Save yegnold/5901983 to your computer and use it in GitHub Desktop.
Helping @cole007 get a htaccess rewrite rule working
RewriteEngine On
# add-ons rewrite rule. Note absence of slash in "rewrite to" (second portion of rewriterule)
# this makes the rewrite relative to the directroy of the .htaccess file unless RewriteBase is defined
RewriteRule ^add-ons/apps/([a-zA-Z0-9-/]+)$ add-ons/apps.php?s=$1 [L]
# The "most generic" rule comes last, as "more specific" rules should match first.
# Added a check to see if we've already got .php in the URL.
RewriteCond %{REQUEST_URI} !.php$
RewriteRule ^(.+)$ $1.php [L,QSA]
------------------
COLES HTACCESS ORIGINAL
-----------------
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [R=permanent,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^add-ons/apps/([a-zA-Z0-9-/]+)$ add-ons/apps.php?s=$1 [L]
RewriteRule ^(.+)$ $1.php [L,QSA]
----------------
EDS UPDATED - Use line 31 onwards in your htaccess file for a working version
----------------
RewriteEngine on
# The specific add-ons rewrite rule should come first as it is most specific.
RewriteRule ^add-ons/apps/([a-zA-Z0-9-/]+)$ add-ons/apps.php?s=$1 [L]
# Next, the rule to remove trailing slashes.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [R=permanent,QSA]
# Finally, the "catch all" redirect.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+)$ $1.php [L,QSA]
@yegnold
Copy link
Author

yegnold commented Jul 1, 2013

I get the same, which is encouraging as it means we are definitely doing something wrong :)

@yegnold
Copy link
Author

yegnold commented Jul 1, 2013

OK
The rule:
RewriteRule ^add-ons/apps/([a-zA-Z0-9-/]+)$ add-ons/apps.php?s=$1 [L]
is fine.

It is a problem with

RewriteRule ^(.+)$ $1.php [L,QSA]

I believe that this rule "maps back" to itself, i.e. asda redirects to asda.php with redirects to asda.php.php which redirects to asda.php.php.php.

@cole007
Copy link

cole007 commented Jul 1, 2013

Hmmm, there is a RewriteCond %{REQUEST_FILENAME} !-f that should be preventing redirects on files.
Is there a way to put a RewriteCond to eg ignore anything already with a PHP suffix?

@cole007
Copy link

cole007 commented Jul 1, 2013

Here's the htaccess in full:

RewriteEngine on  
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [R=permanent,QSA]

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

RewriteRule ^add-ons/apps/([a-zA-Z0-9-/]+)$ add-ons/apps.php?s=$1 [L]
RewriteRule ^(.+)$ $1.php [L,QSA]

@yegnold
Copy link
Author

yegnold commented Jul 1, 2013

This is my working test case, I think:

RewriteEngine On

RewriteRule ^add-ons/apps/([a-zA-Z0-9-/]+)$ add-ons/apps.php?s=$1 [L]

RewriteCond %{REQUEST_URI} !.php$
RewriteRule ^(.+)$ $1.php [L,QSA]

@cole007
Copy link

cole007 commented Jul 1, 2013

Was returning error where directories were redirecting too.
However reiterating earlier RewriteCond seems to have fixed!

RewriteEngine on  
# rules go here

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [R=permanent,QSA]

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

RewriteCond $1 !\.php$
RewriteRule ^add-ons/apps/([a-zA-Z0-9-/]+)$ add-ons/apps.php?s=$1 [L]

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

RewriteRule ^(.+)$ $1.php [L,QSA]

Works wouldn't expect to have to (re)state the conditions twice!

Thanks for all your help with this Ed!

@yegnold
Copy link
Author

yegnold commented Jul 1, 2013

Hi cole

a "working implementation" is included in the gist at the top of this page if you refresh

The reason it wasn't working is because the RewriteCond rules (which say that the subsequent rewrite rule should apply only if those conditions are met) only apply to the next rewrite rule. I.e. they apply only to the rewrite rule immediately afterwards, not any other subsequent rewrite rules.

Because you had placed a new rewrite rule in the middle of the conditions and the "catch all" redirect, the conditions were no longer applying to the "catch all" redirect and so the check (does this filename exist in php form - the line that says %{REQUEST_FILENAME}.php -f) - was not being executed for the catch all redirect.

Hopefully his makes sense

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment