How to avoid index.php in Zend Framework route using Nginx rewrite

5,895

Solution 1

You'll need locations similar to this in each of your locations. I'm just writing an example for /blog location:

location /blog/ {
    try_files $uri $uri/ @blog;
}

location @blog {
    rewrite ^/blog/(.*)$ /blog/index.php/$1 last;
}

Also spotted in your config: you might want to use fastcgi_split_path_info in your PHP location:

location ~ ^(.+\.php)(.*)$ {
    include fastcgi_params;
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_pass   localhost:9000;
}   

See documentation for details.

Solution 2

The ideal solution does involve support from the application, in that it should understand what path it is running under. This allows it to select the correct resource to serve, and return correct links and redirects. In this case the nginx config would look something like this:

location / {
    include fastcgi_params;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_script_name;
    fastcgi_pass 127.0.0.1:9000;
}

i.e. simply pass everything[0] through to a specific PHP script. This may actually work with Zend (I haven't used it myself).

If the application can't be modified to understand this, then things get messy with rewriting paths and modifying content. The catch with rewriting is making sure that the rewritten path doesn't get rewritten again. The following will rewrite paths to /index.php and pass them on to Zend.

location ~ \.php(/|$) {
    include fastcgi_params;
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_pass 127.0.0.1:9000;
}

location / {
    rewrite ^/(.*)$ /index.php/$1;
}

If this doesn't work it's probably because Zend isn't handling the request correctly -- check the logs to see what path it is trying to locate.

This isn't going to cause links returned in HTML or redirects sent by Zend to use the path without "index.php" however, and nginx doesn't seem to have a mechanism to modify those. Check if Zend has a way to configure the root path for links and redirects.

[0] You'd obviously want to serve static content directly, I've omitted that.

Share:
5,895

Related videos on Youtube

Adam Benayoun
Author by

Adam Benayoun

I am the co-founder and CEO of Binpress - A discovery service and source-code marketplace. I also have a love for system administration and anything ending with *nix.

Updated on September 18, 2022

Comments

  • Adam Benayoun
    Adam Benayoun over 1 year

    I am trying to get rid of index.php from the default Zend Framework route. I think it should be corrected at the server level and not on the application. (Correct me if I am wrong, but I think doing it on the server side is more efficient).

    I run Nginx 0.7.1 and php-fpm 5.3.3

    This is my nginx configuration

    server {
        listen *:80;
            server_name domain;
            root   /path/to/http;
            index index.php;
            client_max_body_size 30m;
    
            location / {
                    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;
            }
            location /apc {
                    try_files $uri $uri/ /apc.php$args;
            }
    
            location ~ \.php {
                    include /usr/local/etc/nginx/conf.d/params/fastcgi_params_local;
                    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)$ {
                    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;
            }
    
    }
    

    Basically www.domain.com/index.php/path/to/url and www.domain.com/path/to/url serves the same content.

    I'd like to fix this using nginx rewrite.

  • Adam Benayoun
    Adam Benayoun about 12 years
    Thanks for the answer - however this hasn't solved my problem.