本文假设CodeIgniter放在webroot的ci目录下。如果CodeIgniter直接放在webroot下,可同样参看本文,只需要将最后几步略去。

CodeIgniter要求如下形式的路径:

host:port/ci/index.php/controller/method/params

在apache和lighttpd中,如果路径中发现index.php,就会找到index.php,我们只需要简单保证这种格式:

/index.php/controller/method/params

但是在nginx中/index.php会被当成文件路径的一部分,按以上格式访问服务器,服务器寻找路径 /index.php/controller/method/ 下的 params 文件,显然params不存在,导致php-fpm找不到文件,进而出现no input,也即nginx通过以上格式无法找到index.php文件。这就需要我们手动的设置。为了处理这些问题我们要保证php-fpm找到codeIgniter框架index.php且codeIgniter框架可以正确的解析出controller和method。


主要有两个步骤:

1.配置nginx重写规则

#保证php-fpm找到codeIgniter框架index.php
location /ci/ {
    if (!-e $request_filename) {
        rewrite ^/ci/(.*)$ /ci/index.php/$1 last;   # last 表示本次重写以后,继续寻找下一个匹配规则,也即会继续匹配location /ci/index.php
    }
}

location /ci/index.php {
    fastcgi_pass   unix:/var/run/php5-fpm.sock;
    include        fastcgi_params;
    fastcgi_param  SCRIPT_FILENAME    /var/www/ci/index.php;  # 这个是关键,手动设置SCRIPT_FILENAME,可以保证php-fpm找到ci的index.php
}

2.配置codeIgniter框架

#保证codeIgniter框架可以正确的解析出controller和method
#修改CodeIgniter使用REQUEST_URI来处理mvc参数,而不是默认的AUTO
/*
|--------------------------------------------------------------------------
| URI PROTOCOL
|--------------------------------------------------------------------------
|
| This item determines which server global should be used to retrieve the
| URI string.  The default setting of 'AUTO' works for most servers.
| If your links do not seem to work, try one of the other delicious flavors:
|
| 'AUTO'            Default - auto detects
| 'PATH_INFO'       Uses the PATH_INFO
| 'QUERY_STRING'    Uses the QUERY_STRING
| 'REQUEST_URI'     Uses the REQUEST_URI
| 'ORIG_PATH_INFO'  Uses the ORIG_PATH_INFO
|
*/
//$config['uri_protocol']   = 'AUTO';
$config['uri_protocol'] = 'REQUEST_URI';

如果你的CodeIgniter直接在webroot目录中,到这里就应该配置成功了,此时

$_SERVER['REQUEST_URI']='/controller/model/params'

但是对于本例而言,CodeIgniter在webroot的ci目录下,此时

$_SERVER['REQUEST_URI']='/ci/controller/model/params'

可以在CodeIgniter的index.php的最开始hack一下,加上如下语句,替换掉最开始的ci目录:

$_SERVER['REQUEST_URI'] = preg_replace('/\/ci/','',$_SERVER['REQUEST_URI'] );