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:
- Migrate
apache
rewrite rules fromapache
pattern in.htaccess
tonginx
pattern innginx.conf
. Remember nginx server has to be configured to support PATHINFO mode. - 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.

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;
}

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.
}