Nginx重写404

I've spent ages looking on google for any information, and asked around some people (before anyone suggests I go and do so).

The bits of my nginx.conf that aren't working properly are below. What's working : rewrite to BlogHome, Home and About.

What isn't working - rewrites to C_ReadBlogURL and C_ReadAllPosts . These both 404 for some reason, even though the paths are correct. I don't understand why - and I've been puzzling over this all day. I think it may have something to do with them being php files, but I've no idea.

Any help would be greatly appreciated :)

server {
listen   80;


server_name blog.example.com;

root /usr/share/nginx/www/example;
index /views/Read/BlogHome.php;


location / {
    rewrite ^/?$ /views/Read/BlogHome.php last; break;
    rewrite ^/(.+)/?$ /controllers/read/C_ReadBlogURL.php?url=$1 last; break;
}
location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
}
}

server {
listen 80;
server_name example.com;

root /usr/share/nginx/www/example;
index /controllers/read/C_ReadLatestPost.php;

location ~ ^(/posts\.php) {
    rewrite ^(/posts\.php)  /controllers/read/C_ReadAllPosts.php?type=$arg_type last; break;
}

location ~ ^/?$ {
    rewrite ^/?$ /controllers/read/C_ReadLatestPost.php last; break;


}

location ~ ^(/about)/?$ {
    rewrite ^(/about)/?$ /views/Read/About.php last; break;
}

location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
}

}

Remove every "break;" in each of your rewrite rules. It doesn't belong here. Any rewrite rules after the first "break;" directive will be ignored. Don't think that's what you want.

reference: http://wiki.nginx.org/HttpRewriteModule#break

[UPDATE] Based on the nginx config file from the comment below.

Note that "break directive is different from "rewrite...break;" My major change is to move the 2 rules into the php location block, and replace 'last' by 'break' such that it won't trigger another round to location search.

Your 2nd rewrite rule is wrong (using "[]" is different from "()" in regex). My understanding is that you want to match all the remaining php scripts. So I changed that rule.

I also remove another appearance of "break;" from "location /" block. You may only want to put a 'break;' directive inside an IF block. Other than that, I don't see any practical usage of that directive.

[UPDATE2] Also it makes sense to move everything to the "location /" block as well.

server {
    listen 80;
    server_name blog.example.com;
    root /usr/share/nginx/www/example;
    index /views/Read/BlogHome.php;

    location / {
        rewrite ^(/posts\.php) /controllers/read/C_ReadAllPosts.php?type=$arg_type break;
        rewrite ^/?$ /views/Read/BlogHome.php break;
        rewrite ^ /controllers/read/C_ReadBlogURL.php?url=$uri break;

        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
   }
}

The () aren't necessary in the first rule, but that is just a detail.

I think that your problem is the "break;", only "last;" is the correct choice for this case.

I tried this and it works(test1.html and test2.html have different content and I know when is entering in each rule):

rewrite ^/posts.php /test1.html?type=$arg_type last;
rewrite ^/(.+)/?$ /test2.html?url=$1 last;

So, for you this should work:

rewrite ^/posts.php /controllers/read/C_ReadAllPosts.php?type=$arg_type last;
rewrite ^/(.+)/?$ /controllers/read/C_ReadBlogURL.php?url=$1 last;

or according to your last update:

rewrite ^/posts\.php /controllers/read/C_ReadAllPosts.php?type=$arg_type last;
rewrite ^/?$ /views/Read/BlogHome.php last;
rewrite ^/(.+)/?$ /controllers/read/C_ReadBlogURL.php?url=$uri last;