master techniques migrating php from apache to nginx, configuring nginx to support PATHINFO and debugging nginx rewrite rules

master techniques migrating php from apache to nginx, configuring nginx to support PATHINFO and debugging nginx rewrite rules

When I was migrating an old web site written in PHP from under Apache2 to Nginx I met a strange problem that the site worked perfectly under Apache2 but crashed for every sub-page under nginx.

The reason was that apache uses rewrite rule with its mod_rewrite and the corresponding php code gets the rewritten url parameter from $_SERVER[REDIRECT_URL]. But nginx does not support that.

I learnt it the hard way so I’d like to write the solution down in case other people met the same problem when migrating from apache to nginx+ php-fpm.

The solution to this problem is sumarized into two steps:

  1. Migrate apache rewrite rules from apache pattern in .htaccess to nginx pattern in nginx.conf. Remember nginx server has to be configured to support PATHINFO mode.
  2. php code has to be modified to use $_SERVER[PATH_INFO]for url.

For step 1, here’s an example ofnginx.conf code snippet. Just copy it into your own nginx.conf file under server section.

server {
    ...

    location / {        
        if (!-e $request_filename) {
            rewrite  ^/(.*)$  /index.php/$1  last;
                    break;
        }
    }
     
    location ~ \.php {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fcgi.conf;
        set $real_script_name $fastcgi_script_name;
        if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
            set $real_script_name $1;
            set $path_info $2;
        }
        fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
        fastcgi_param SCRIPT_NAME $real_script_name;
        fastcgi_param PATH_INFO $path_info;
    }
   ...
}

For step2, please see these two lines of php code getting $_SERVER[REDIRECT_URL] and $_SERVER[PATH_INFO] in the picture below.

The php source code using pathinfo mode is highlighted. You should change the code accordingly, of course.

$_SERVER[PATH_INFO] usage

Here I’d mension a small technique to debug nginx rewrite rule.

In your nginx.conf file, write the following code snippet to record rewrite rule log in nginx’s error log.

server {
        error_log    /var/logs/nginx/example.com.error.log;
        rewrite_log on;
}
nginx rewrite log

Remember to close it with rewrite_log off; when you finish debugging.

To write logs only from a targeted ip:

events {
        debug_connection 1.2.3.4; # your targeted ip address here.
}

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.