我正在使用Nginx和Codeigniter以及php5-fpm。一切"似乎"都工作得很好,页面显示出来,一切看起来都很棒。Ofcource这不是我在这里问这个问题的原因,我实际上有一个问题。
我面临的问题是页面抛出了 404 错误,即使页面正确呈现,我仍然会得到 404(在日志中)。
我得到 404 的原因是 Nginx 无法打开我请求的文件,因为 Nginx 尝试直接打开 PHP 文件,而不是引用controller/method
不幸的是 Codeigniter 以这种方式工作。
例如:
请求http://website.com/<controller>/<function>/<other_params>
会导致 Nginx 日志中的 404,这背后的原因是open()
无法打开指定的目录,因为它不存在,而不是引用controller/method
。
一些重要的日志:
Nginx错误日志:
[error] 4172#0: *482 open() "/var/www/<domain>/public/site/section/main" failed
(2: No such file or directory), client: <client_ip>, server: <domain>, request: "GET
/site/section/main HTTP/1.1", host: "<domain>"
正如我之前所说,Nginx试图直接访问该文件,而不是让Codeigniter处理它。
我的sites-enabled/ci
配置:
server
{
server_name <domain> *.<domain>;
access_log /var/www/<domain>/access.log;
error_log /var/www/<domain>/error.log;
root /var/www/<domain>/public;
index index.php index.html index.htm;
location ~* '.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
access_log off;
log_not_found off;
expires 360d;
}
# enforce www (exclude certain subdomains)
# if ($host !~* ^(www|subdomain))
# {
# rewrite ^/(.*)$ $scheme://www.$host/$1 permanent;
# }
# enforce NO www
if ($host ~* ^www'.(.*))
{
set $host_without_www $1;
rewrite ^/(.*)$ $scheme://$host_without_www/$1 permanent;
}
# canonicalize codeigniter url end points
# if your default controller is something other than "welcome" you should change the following
if ($request_uri ~* ^(/site(/index)?|/index(.php)?)/?$)
{
rewrite ^(.*)$ / permanent;
}
# removes trailing "index" from all controllers
if ($request_uri ~* index/?$)
{
rewrite ^/(.*)/index/?$ /$1 permanent;
}
# removes trailing slashes (prevents SEO duplicate content issues)
# if (!-d $request_filename)
# {
# rewrite ^/(.+)/$ /$1 permanent;
# }
# removes access to "system" folder, also allows a "System.php" controller
if ($request_uri ~* ^/(system|application))
{
rewrite ^/(.*)$ /index.php?/$1 last;
break;
}
# unless the request is for a valid file (image, js, css, etc.), send to bootstrap
#if (!-e $request_filename)
#{
# rewrite ^/(.*)$ /index.php?/$1 last;
# break;
#}
# catch all
error_page 404 /index.php;
# use fastcgi for all php files
location ~ '.php($|/)
{
#if (!-e $request_filename) {
# return 404;
# }
fastcgi_pass 127.0.0.1:9000;
#fastcgi_pass php5-fpm-sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# location / {
# try_files $uri $uri/ @codeigniter;
#}
# location @codeigniter {
# rewrite ^(.*) /index.php?$1 last;
# }
# deny access to apache .htaccess files
location ~ /'.ht
{
deny all;
}
}
那么,Nginx和Codeigniter之间这种误解背后的原因是什么呢?
提前谢谢。
您的配置中似乎没有规则告诉nginx在找不到文件时尝试向php发送请求。有一个注释掉的块,上面有try_files
和@codeigniter
,几乎看起来像它。从理论上讲,这就是你想要nginx做的:
- 检查网址是否存在,如果确实提供它。
- 将其他所有内容发送到编码点火器并让它整理。
为此,这两个块应该足够了:
location / {
# Check if a file exists, or route it to index.php.
try_files $uri $uri/ /index.php;
}
location ~ '.php$ {
# for security, see http://forum.nginx.org/read.php?2,88845,page=3
try_files $uri =404;
fastcgi_split_path_info ^(.+'.php)(.*)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
其他if
受保护的块不应与这些块一起中断。