Remove 'index.php' from URL with .htaccess - regex

I've been trying all sorts of solutions from this site and none seem to work. I'm currently hosting with hostgator. This is my current .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>
<IfModule mod_suphp.c>
suPHP_ConfigPath /home/user/php.ini
<Files php.ini>
order allow,deny
deny from all
</Files>
</IfModule>
This is in the root folder of my site. I have also tried adding a ? after index.php and no luck. Does anyone know why this isn't working?

This is the code you can use in your .htaccess (under DOCUMENT_ROOT) to remove index.php from URI:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [L,QSA]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.*)/index\.php [NC]
RewriteRule ^ %1 [R=301,L]

Symfony 2 has an excellent solution:
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
# Sets the HTTP_AUTHORIZATION header removed by apache
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^index\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
RewriteRule .? %{ENV:BASE}/index.php [L]
This accomplishes the following:
RewriteBase is not necessary (useful when the site is in a subdirectory beneath the web root)
index.php is removed if present
The request is routed to the correct index.php with the full query string from the original request
Note that the line:
RewriteRule ^(.*) - [E=BASE:%1]
is responsible for setting the %{ENV:BASE} variable for later on. Refer to Apache documentation on E|env flag.

I tried this and works fine:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# Removes index.php from ExpressionEngine URLs
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteCond %{REQUEST_URI} !/system/.* [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
# Directs all EE web requests through the site index file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>
Exceptions
If your site’s system directory (/system/) has been renamed and is still accessible by URL, modify the RewriteCond line above:
RewriteCond %{REQUEST_URI} !/newdirectoryname/.* [NC]
If you are running EE from a sub-directory rather from the root of your domain (e.g. http://example.com/myeesite/ instead of http://example.com/), just remove the slash preceding index.php in the RewriteRule line above, like so:
RewriteRule ^(.*)$ index.php/$1 [L]
If you are running EE from a sub-directory and it still doesn’t work after removing the slash, you may need to specify the sub-directory in your rewrite rule. For example, if your sub-folder is named testing, change:
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
To:
RewriteRule (.*?)index\.php/*(.*) testing/$1$2 [R=301,NE,L]
And change:
RewriteRule ^(.*)$ /index.php/$1 [L]
To:
RewriteRule ^(.*)$ testing/index.php/$1 [L]
If your host requires forcing query strings, try adding a question mark following index.php in the RewriteRule line above, like so:
RewriteRule ^(.*)$ /index.php?/$1 [L]

To remove index.php from urls on apache2.4 you can use the following rule :
RewriteEngine on
RewriteRule ^index\.php/(.+)$ /$1 [L,R]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !index\.php /index.php%{REQUEST_URI} [L,END]
This will change the uri
/index.php/foobar
to
/foobar
This rule will return an internal server error for lower versions of apache as they don't support the END flag. Please see the anubhava's answer above that works almost on all versions.

I've been compelled to join stack overflow.com today to comment here as the answer has solved a long term problem I've had with a Zend Framework website. I've worked on the website around 3 1/2 years and during that time I discovered that it didn't handle index.php correctly and this causes webmaster tools to see duplicate titles etc.
I decided to search again today for a solution, one of many times attempted.
This is the one (the last answer shown above) that solves my problem.
# Removes index.php from ExpressionEngine URLs
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteCond %{REQUEST_URI} !/system/.* [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
As an example. this is what it achieves for me.
http://www.domainname.co.uk/index.php/categories/url-name.html
becomes
http://www.domainname.co.uk/categories/url-name.html
Thank you to everyone who contributed to the original question as it lead to the answer and solution above.
Extra Note: I have other rewrite commands that handles the other aspects but those on their own didn't fix the index.php and the only time this has been fixed is by using.
# Removes index.php from ExpressionEngine URLs
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteCond %{REQUEST_URI} !/system/.* [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
I only hope it helps others whether its ExpressionEngine or Zend Framework, in the future.

Related

Redirecting from /index.php to / not working

The dynamic pages in my site are configured with following htaccess rule:
# Dynamic Pages
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
So the page is redirected from
http://example.com/?url=testpage
to
http://example.com/testpage/
But I also want to redirect /index.php to / (root). So when someone enters
http://example.com/index.php
in the browser address bar then it should go to
http://example.com/
To achieve this, I tried following rule:
#index.php to /
RewriteRule ^index\.php$ / [R=301]
Though this is working fine but it is affecting my previous htaccess rule. And the following URL
http://example.com/testpage/
automatically becomes
http://example.com/?url=testpage
When I remove this rule then previous dynamic page rule works fine. How can I keep both rules working in my htaccess file without conflicting each other?
My complete .htaccess file is:
Options +FollowSymlinks -MultiViews
#Enable mod rewrite
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
# Dynamic Pages
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
# index.php to /
RewriteRule ^index\.php$ / [R=301]
You can use these rules:
Options +FollowSymlinks -MultiViews
#Enable mod rewrite
RewriteEngine On
# index.php to /
RewriteCond %{THE_REQUEST} /index\.php [NC]
RewriteCond %{REQUEST_URI} ^(.*/)index\.php$ [NC]
RewriteRule ^ %1 [L,R=301,NE]
# Dynamic Pages
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php?url=$0 [QSA,L]
Important is to use THE_REQUEST in first rule so that you don't get rewrite loop. Clear your browser cache to test.

.htaccess rewrite troubles with /index.php

I have a small site with about 10 pages.
So I have made it so that the URL structure is rewritten via .htaccess simply: www.domain.com/name.php becomes www.domain.com/name
The trouble now is that I added some more pages and folder and want it to recognise: www.domain.com/foldername/
However it just cannot manage it. It gives me a 404 page not found as it is searching for www.domain.com/foldername/.php
My .htaccess code is below. Any help would be greatly appreciated!
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^www\.domain\.com\
RewriteRule (.*) http://www.domain.com/$1 [R=301,L]
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Have your rule check for existence of corresponding .php file before adding .php extension:
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.domain\.com$
RewriteRule (.*) http://www.domain.com/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([^.]+?)/?$ $1.php [L]

Use .htaccess to rewrite a sub directory to root but keep access to other sub directories

I am trying to rewrite a subdirectory out of my URL structure but have other URLs within that directory structure also work. I have this scenario:
// This should load the content of mysite.com/foo/15 but not redirect
mysite.com/foo/
// Subdirectories within /15 should also work
mysite.com/foo/bar // the actual location of this is mysite.com/foo/15/bar
// Other URLs within this directory structure should also work, such as
mysite.com/foo/12
mysite.com/foo/13
mysite.com/foo/14
// Lastly, we have redirects from 2012 -> 12, 2013 -> 13 such that
mysite.com/foo/2012 becomes mysite.com/foo/12
mysite.com/foo/2013 becomes mysite.com/foo/13
... and so on
Here's where i'm at. I can't get the right combination of htaccess rules to achieve what I want.
RewriteEngine On
RewriteBase /foo/
// This makes mysite.com/foo/ load the content of mysite.com/foo/15 without redirecting, but makes mysite.com/foo/14 404
RewriteRule ^((?!15/).*)$ 15/$1 [NC,L]
// This works pretty well, except the rules below don't redirect
RewriteRule ^$ 15/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ 15/$1
// Rewrite old years to the two digit form
RewriteRule ^2010/(.*)$ 10/$1 [R=301]
RewriteRule ^2011/(.*)$ 11/$1 [R=301]
RewriteRule ^2012/(.*)$ 12/$1 [R=301]
RewriteRule ^2013/(.*)$ 13/$1 [R=301]
RewriteRule ^2014/(.*)$ 14/$1 [R=301]
RewriteRule ^2015/(.*)$ 15/$1 [R=301]
What am I missing? What combination of rules will help me achieve what i'm looking for?
Your redirect rules can be combined into single rule using regex matching:
RewriteEngine On
RewriteBase /foo/
// Rewrite old years to the two digit form
RewriteRule ^20(1[0-5])/(.*)$ $1/$2 [R=301,L]
RewriteRule ^$ 15/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^((?!15/).*)$ 15/$1 [L]
Try including the L flag in all your rules and then put all your redirects at the top of the htaccess file:
RewriteEngine On
RewriteBase /foo/
// Rewrite old years to the two digit form
RewriteRule ^2010/(.*)$ 10/$1 [R=301,L]
RewriteRule ^2011/(.*)$ 11/$1 [R=301,L]
RewriteRule ^2012/(.*)$ 12/$1 [R=301,L]
RewriteRule ^2013/(.*)$ 13/$1 [R=301,L]
RewriteRule ^2014/(.*)$ 14/$1 [R=301,L]
RewriteRule ^2015/(.*)$ 15/$1 [R=301,L]
// This makes mysite.com/foo/ load the content of mysite.com/foo/15 without redirecting, but makes mysite.com/foo/14 404
RewriteRule ^((?!15/).*)$ 15/$1 [NC,L]
// This works pretty well, except the rules below don't redirect
RewriteRule ^$ 15/ [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ 15/$1 [L]

.htaccess not working only with internet explorer

i have site, that has to rewrite site.ru and www.site.ru to www,site.ru/ru_RU.
I can't access any Apache config files. In htaccess:
Options +FollowSymLinks
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^site.ru$
RewriteRule (.*) http://www.site.ru/ru_RU [QSA]
RewriteCond %{HTTP_HOST} ^www.site.ru$
RewriteRule (.*) http://www.site.ru/ru_RU [QSA]
RewriteCond %{REQUEST_URI} ^/news
RewriteRule (.*) /news [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?page=$1 [QSA]
</IfModule>
It's working in firefox or chrome, but in IE i get "this page can't be displayed". Tested on IE10 and IE8 (not compatibility view) on few computers.
If i write some junk in .htacess, i get 500 error in IE. Without .htaccess site loads ok, but i need it to rewrite url. Any ideas how to fix it?
Your flags are all wrong. Modify your rules to this:
Options +FollowSymLinks
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^site\.ru$ [NC]
RewriteRule ^ http://www.site.ru/ru_RU [L,R]
RewriteCond %{HTTP_HOST} ^www\.site\.ru$ [NC]
RewriteRule !ru_RU /ru_RU [NC,L,R]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?page=$1 [L,QSA]
</IfModule>
Reference: Apache mod_rewrite Introduction
I can't test it now, but here is my guess:
I think http_host ONLY contains the host part, not the uri. So you end up with an endless loop as www.site.ru is will always match again after your rewrite.
You will need another rule that checks if the uri is empty. Like this (untested):
RewriteCond %{REQUEST_URI} ^$
RewriteRule (.*) /ru_RU [QSA]
You might need another condition for the case that the uri contains a slash.

Rewrite/redirect urls to subdomain

I have an add-on on domain that is finally registered and can be accessed without the main domain. The add-on domain have been used like this: (I didn't find similar domain setup to help me out with this)
primary.com/secondary.de/
primary.com/secondary.de/files
primary.com/secondary.de/files/file
I'd like to redirect users to:
secondary.de/
secondary.de/files
secondary.de/files/file
addresses. What expressions should I use in my htacces file?
Thanks
Since this is WP install, put this code in your .htaccess under DOCUMENT_ROOT/secondary.de directory:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^(www\.)?primary\.com$ [NC]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+(secondary\.de/[^\s]*) [NC]
RewriteRule ^ http://%1 [NE,R=301,L,NC]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>