这是在CentOS 7.2中通过PHP-FPM使用nginx 1.6.3和PHP 7.0.7。
我已经运行了很多使用LAMP的站点,并且一直在尝试切换到LEMP,但是一直持续不断的问题是,即使我在PHP中设置了不同的状态,我的页面处理程序仍然在状态中显示404错误。 就好像nginx完全忽略了从PHP发送的404错误页面的头文件。
/etc/nginx/nginx.conf看起来像:
user web web; worker_processes auto; error_log /var/web/Logs/WebServer/nginx-error.log; pid /run/nginx.pid; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/web/Logs/WebServer/nginx-access.log main; fastcgi_buffers 8 1024k; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; include /etc/nginx/conf.d/*.conf; }
每个域的configuration如下所示:
server { listen 80; server_name www.something.com; root /var/web/www.something.com/; index index.php index.html; error_page 404 /PageHandler; location / { try_files $uri $uri/ /PageHandler =404; location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; fastcgi_index index.php; include fastcgi.conf; } location /PageHandler { try_files /PageHandler.php =500; fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; include fastcgi.conf; fastcgi_param REDIRECT_STATUS 404; } } }
非常简单的PHP脚本(是的,我知道标题是多余的,但它什么也没有):
<?php http_response_code(200); header("HTTP/1.1 200 OK"); header("Status: 200", true, 200); ?> Test <?= $_SERVER["REQUEST_URI"] ?>, code <?= $_SERVER["REDIRECT_STATUS"] ?>
我已经无果地search了几个小时,如何解决这个问题。 我已经尝试了至less一百个不同的.conf格式,并没有一个工作。 我上面至less将REDIRECT_STATUS设置为404,但如果find页面,我找不到能够返回200状态码的方法。 我不能只是让nginx总是返回一个200,因为它实际上可能是一个真正的404,因为实际的脚本testing数据库中的当前URL。
如何让nginx服从PHP的HTTP状态头?
对我来说,这些嵌套的location块看起来很麻烦,而且不需要它们。 尝试这个:
server { listen 80; server_name www.something.com; root /var/web/www.something.com/; index index.php index.html; try_files $uri $uri/ /PageHandler.php =404; location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; fastcgi_index index.php; include fastcgi.conf; } }
显而易见的事情是删除这个:
error_page 404 /PageHandler;
这是完全多余的,因为任何不是静态文件的path都会被第一个try_files指向。 仅使用error_page来提供静态错误页面是必要的或有用的。
通过结合我从许多失败中学到的教训,我收到了另外两个答案(感谢迈克尔·汉普顿和特罗·基尔卡宁指引我朝着正确的方向),以及进一步研究try_files的预感,我发现问题是围绕着如何try_files在我的安装工作。 这里有更多的细节: try_files是如何工作的? 在这里: http : //nginx.org/en/docs/http/ngx_http_core_module.html#try_files
最终的工作服务器configuration是:
server { listen 80; server_name www.something.com; root /var/web/www.something.com/; index index.php index.html; try_files $uri $uri/ @PageHandler; location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; fastcgi_index index.php; include fastcgi.conf; } location @PageHandler { try_files /PageHandler.php =404; fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; include fastcgi.conf; fastcgi_param REDIRECT_STATUS 404; } }
正如你所看到的,我正在使用一个@PageHandler的命名位置并绑定在那里。 它使用默认的HTTP状态200而不是404,但是因为我可以从PHP控制它,所以在必要时将其明确地设置为404。
使用下面的任何一个PHP命令都会改变浏览器的状态(所有这三个都不是必需的):
http_response_code(404); header("HTTP/1.1 404 Not Found"); header("Status: 404", true, 404);