17

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?

anubhava
  • 761,203
  • 64
  • 569
  • 643
Norse
  • 5,674
  • 16
  • 50
  • 86
  • What are you trying to do? What is happening instead? Are you visiting `/index.php?magic` and expecting a redirect to `/magic`? – Tim Mar 07 '12 at 20:16
  • 1
    Is your web host running an apache server :D ? – bbedward Mar 07 '12 at 20:17
  • @TIM I have link on `www.mysite.com/post.php` that leads to `href='index.php'`, and that link takes me to `www.mysite.com/index.php` instead of `www.mysite.com`.... if that makes sense. – Norse Mar 07 '12 at 20:19

5 Answers5

54

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]
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 2
    What would need to change in these rules for a url like this `http://site.com/index.php/Page/Param1/Param2` because it seems like the whole url is getting cut off after the domain for me. – Metropolis Jul 18 '12 at 14:42
  • I would like in the address bar to look like `http://site.com/Page/Param1/Param2` even though PHP needs to recieve it as `http://site.com/index.php/Page/Param1/Param2`. – Metropolis Jul 19 '12 at 14:44
  • Thanks anubhava. Here is the link to my question `http://stackoverflow.com/questions/11567652/how-do-you-remove-inex-php-from-a-url-using-mod-write-while-still-allowing-php` – Metropolis Jul 19 '12 at 19:07
  • 1
    I was going to edit the answer but I'm not 100% sure. I'm fairly certain you need a / between \s and (.*) since otherwise the rewrite ends up with a double slash. `^[A-Z]{3,}\s/(.*)/index\.php` either this, or removing the slash from before %1. Either solve the problem on my end. Just not sure about all types of servers. – Dustin Graham Sep 19 '13 at 22:36
  • Using your code, how do I strip or trim the `.php` or `.html` extension on existing pages? ...what if I don't want to go back and manually rename existing `` tags that already include the extension(s)? – Uncle Iroh Jul 28 '16 at 18:33
  • 1
    @MaggewDotCom: Try: http://stackoverflow.com/a/28091526/548225 and if it doesn't work, post a new question. – anubhava Jul 28 '16 at 18:44
  • 1
    Your code worked for me with a little change. I added a /. Turned RewriteRule ^ %1 [R=301,L] to RewriteRule ^ /%1 [R=301,L] – Usman Ahmed Dec 09 '17 at 06:32
7

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.

afeique
  • 395
  • 6
  • 15
Frédéric Klee
  • 145
  • 1
  • 9
2

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]
Vivek Ghaisas
  • 961
  • 1
  • 9
  • 24
stampgo
  • 21
  • 3
2

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.

Amit Verma
  • 40,709
  • 21
  • 93
  • 115
1

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.

Paul
  • 11
  • 1