# Removing index.php from url

**URL:** <https://www.ruby-forum.com/t/removing-index-php-from-url/224923>\
**Category:** NGINX\
**Created:** [December 3, 2012, 1:09am UTC](https://www.ruby-forum.com/t/removing-index-php-from-url/224923 "2012-12-03T01:09:52Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![aris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/258eb7/32.png) [@aris](https://www.ruby-forum.com/u/aris)\
**Post date:** [December 3, 2012, 1:09am UTC](https://www.ruby-forum.com/t/removing-index-php-from-url/224923/1 "2012-12-03T01:09:52Z")

</div>

Hey all,  
I have a server with nginx 1.2.5 and php-fpm 5.3.3 installed. I have a  
web  
application built on top of zend framework and the routing passes  
everything  
thru a index.php file.  
So while [http://www.domain.com/contact](http://www.domain.com/contact) works -  
[Domain.com](http://www.domain.com/index.php/contact) will fetch the same content  
aswell  
and I’d like to get rid of it for SEO purpose.

Here’s my configuration - right now there’s a if statement that takes  
care  
of removing the index.php however I know that if is evil and therefore  
shouldn’t be used. On top of that the only instance that won’t work well  
is  
[Domain.com](http://www.domain.com/index.php) which in this case instead of  
redirecting to  
[www.domain.com](http://www.domain.com) will just display a blank page with a 301 status code.

On top of that - if you guys spot any problem with my config - I’d love  
to  
hear what I am doing wrong and what can be improved.

server {  
listen \*:80;  
server\_name [domain.com](http://domain.com);  
return 301 $scheme://www.domain.com$request\_uri;  
}  
server {  
listen 80;  
listen 443 ssl;  
server\_name [www.domain.com](http://www.domain.com);  
ssl\_certificate /etc/nginx/certs/www.domain.com.crt;  
ssl\_certificate\_key /etc/nginx/certs/www.domain.com.key;  
error\_log /var/www/domain/logs/error\_log warn;  
root /var/www/domain/html/http;  
index index.php;  
client\_max\_body\_size 150m;  
error\_page 403 404 [http://www.domain.com/notfound](http://www.domain.com/notfound);

if ( $request\_uri ~ “^/index.php” ) {  
rewrite ^/index.php(._) $1 permanent;  
}  
location / {  
rewrite ^/wanted/feed$ /feed?filter=wanted permanent;  
try\_files $uri $uri/ /index.php?$args;  
}  
location /min {  
try\_files $uri $uri/ /min/index.php?q=;  
}  
location /blog {  
try\_files $uri $uri/ /blog/index.php?q=$1;  
}  
location /apc {  
try\_files $uri $uri/ /apc.php$args;  
}  
location ~ .php {  
include /etc/nginx/fastcgi\_params;  
fastcgi\_param HTTPS $https if\_not\_empty;  
fastcgi\_param SCRIPT\_FILENAME $document\_root$fastcgi\_script\_name;  
fastcgi\_param PATH\_INFO $fastcgi\_script\_name;  
fastcgi\_param SERVER\_NAME $http\_host;  
fastcgi\_pass 127.0.0.1:9000;  
}  
location ~_ ^.+.(ht|svn|git)$ {  
deny all;  
}

# Static files location

location ~\*  
^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$  
{  
expires max;  
}  
}

Posted at Nginx Forum:

> **[Removing index.php from url](https://forum.nginx.org/read.php?2,233476,233476#msg-233476)**
>
> Hey all, I have a server with nginx 1.2.5 and php-fpm 5.3.3 installed. I have a web application built on top of zend framework and the routing passes everything thru a index.php file. So while http://www.domain.com/contact works -...

---

<div class="post-metadata">

**Author:** ![adambenayoun](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/e36b37/32.png) [@adambenayoun](https://www.ruby-forum.com/u/adambenayoun)\
**Post date:** [December 3, 2012, 3:00am UTC](https://www.ruby-forum.com/t/removing-index-php-from-url/224923/2 "2012-12-03T03:00:57Z")

</div>

2012/12/03 7:09 “adambenayoun” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Hey all,  
> I have a server with nginx 1.2.5 and php-fpm 5.3.3 installed. I have a web  
> application built on top of zend framework and the routing passes  
> everything  
> thru a index.php file.  
> So while [http://www.domain.com/contact](http://www.domain.com/contact) works -  
> [http://www.domain.com/index.php/contact](http://www.domain.com/index.php/contact) will fetch the same content aswell  
> and I’d like to get rid of it for SEO purpose.
> 
> Here’s my configuration - right now there’s a if statement that takes care  
> of removing the index.php however I know that if is evil and therefore  
> shouldn’t be used. On top of that the only instance that won’t work well  
> is  
> [http://www.domain.com/index.php](http://www.domain.com/index.php) which in this case instead of redirecting  
> to  
> [www.domain.com](http://www.domain.com) will just display a blank page with a 301 status code.

location = /index.php { return 301 /; }  
location ~ ^/index.php(/.\*) { return 301 $1; }

Note that the $1 may or may not work as I never tested that.

> listen 80;  
> if ( $request\_uri ~ “^/index.php” ) {  
> try\_files $uri $uri/ /blog/index.php?q=$1;  
> fastcgi\_pass 127.0.0.1:9000;  
> }  
> location ~\* ^.+.(ht|svn|git)$ {  
> deny all;  
> }
> 
> # Static files location
> 
> location ~\*

^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$

> {  
> expires max;  
> }  
> }
> 
> Posted at Nginx Forum:  
> [http://forum.nginx.org/read.php?2,233476,233476#msg-233476](http://forum.nginx.org/read.php?2,233476,233476#msg-233476)

---

<div class="post-metadata">

**Author:** ![adambenayoun](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/e36b37/32.png) [@adambenayoun](https://www.ruby-forum.com/u/adambenayoun)\
**Post date:** [December 3, 2012, 10:11pm UTC](https://www.ruby-forum.com/t/removing-index-php-from-url/224923/3 "2012-12-03T22:11:52Z")

</div>

On Sun, Dec 02, 2012 at 07:08:55PM -0500, adambenayoun wrote:

Hi there,

I don’t have a direct answer to your questions, but there is something  
I’d like to comment on…

> So while [http://www.domain.com/contact](http://www.domain.com/contact) works -  
> [http://www.domain.com/index.php/contact](http://www.domain.com/index.php/contact) will fetch the same content aswell  
> and I’d like to get rid of it for SEO purpose.

“get rid of” means: if a request comes in for /index.php/anything,  
it should be permanently redirected to /anything.

> right now there’s a if statement that takes care  
> of removing the index.php however I know that if is evil and therefore  
> shouldn’t be used.

Here’s the thing: why do you believe that? It seems to be a reasonably  
common belief.

The wiki page about it, [GitHub - nginxinc/nginx-wiki: ARCHIVED -- Source for the now archived NGINX Wiki section of https://www.nginx.com · GitHub](http://wiki.nginx.org/IfIsEvil), has as its first  
line: “Directive if has problems when used in location context”. You’re  
not using it in location context, so you should be fine. Outside of  
location context, I don’t think it counts as any more evil than any of  
the rewrite module directives.

Anyway: on to the questions…

> On top of that the only instance that won’t work well is  
> [http://www.domain.com/index.php](http://www.domain.com/index.php) which in this case instead of redirecting to  
> [www.domain.com](http://www.domain.com) will just display a blank page with a 301 status code.

So: what do you want to happen when someone requests /index.php without  
an immediately-following / ? Just process the page, or redirect to / ?

[Module ngx\_http\_core\_module](http://nginx.org/r/location) for the details, but you can use “location  
= /” or “location = /index.php” to handle the “exact” case (which can  
involve fastcgi\_pass and the like); then “location ^~ /index.php/” for  
everything that should be redirected to “no index.php” (possibly with  
a map ([Module ngx\_http\_map\_module](http://nginx.org/r/map)) to find the thing to redirect to); and  
then the rest stays as it is.

> On top of that - if you guys spot any problem with my config - I’d love to  
> hear what I am doing wrong and what can be improved.

> error\_page 403 404 [http://www.domain.com/notfound](http://www.domain.com/notfound);

That bit possibly does not do what you want.

> if ( $request\_uri ~ “^/index.php” ) {  
> rewrite ^/index.php(.\*) $1 permanent;  
> }

With the pure-location setup, that bit becomes unnecessary.

> location /min {  
> try\_files $uri $uri/ /min/index.php?q=;

No $args there.

> location /blog {  
> try\_files $uri $uri/ /blog/index.php?q=$1;

It’s not obvious what $1 is set to there.

> location /apc {  
> try\_files $uri $uri/ /apc.php$args;

No ? there.

Each of those may or may not do what you want. If they work, that’s  
fine.

> location ~ .php {

> location ~\* ^.+.(ht|svn|git)$ {

> location ~\*

An occasional suggestion on the list is to avoid top-level regex match  
locations, for ease of reading/scalability reasons.

If you choose to follow that suggestion, those would need to be  
rewritten.

It may not be worth you following that suggestion, depending on how your  
files are organised.

Cheers,

## f

Francis D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
