当CodeIgniter遇到Nginx报404错误的解决办法

由于CodeIgniter当初是设计在apache的,而apache对pathinfo是支持比较好的,所以一切都很nice。但是当你把写好的代码放到nginx上,傻眼了,可能出了CodeIgniter的welcom之外,其他都是404错误。而我惊奇的发现,CodeIgniter的官方文档竟然对在Nginx上的配置只字不提。而你百度”CodeIgniter Nginx 404”又能搜到一堆一堆的文章,奇葩的是几乎每个文档的配置方法貌似还不大一样。如果你搞好了还罢,搞不好就是配几个晚上都搞不定,像我一样。(本文服务器环境:CentOS,nginx-1.4.7,php-5.4.24,CodeIgniter3.0.2--当前最新版本)

404错误的原因

原因是默认Nginx不支持pathinfo这种格式,当你浏览器里输入http:\xxx.xxx.com\index.php\pages\home的时候,Nginx会认为你要访问index.php目录下的pages文件夹里的home,所以会报404 not found错误。

解决方法

解决方法肯定是要修改服务器的重定向规则,大概有两种思路,一种是改nginx安装目录里的nginx.conf文件,如果你用了虚拟主机的话就去nginx安装目录下的vhosts下找对应的*.conf更改即可。另外一种思路修改CI目录下的.htaccess文件,参见:http://blog.csdn.net/freshlover/article/details/8977111
本文是第一种思路。在修改之前先来看下原始的conf文件:

{
       listen 80;
       server_name 1.abc.com 2.abc.com;
        root /a/domains/1.abc.com/public_html;
        index index.html index.htm index.shtml index.php;

        error_page  404               /404.html;
    #Custom rules Start
        #Custom rules End
    location = /500.html {
        root   /usr/share/nginx/html;
    }

    location ~ \.php$ {
        fastcgi_pass   unix:/dev/shm/php.sock;
        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        access_log     /a/apps/nginx/logs/1.abc.com.access.log main;
    }


    location ~ /\.ht {
        deny  all;
    }
}

PS:上面为了隐私,我把server_name改为1.abc.com了,这个对应自己的server_name.
下面介绍修改方法,在修改conf前切记将自己的conf,cp为conf.back备份一份。
下面为修改方法:
1,修改php支持pathinfo
再修改conf之前,找到php的php.ini文件(可能在php安装目录的etc目录也可能在lib文件夹下,看自己的配置),搜索:cgi.fix_pathinfo
将注释放开,并置为1:cgi.fix_pathinfo=1

2,修改conf之前有个问题要明确,那就是CI的根目录 是不是web的root目录,如果是的话,如下修改:
只需要增加如下即可:
在location ~ .php$之前增加一段:

     if (!-e $request_filename) {
          rewrite ^.*$ /index.php last;
     }

这个意思是,如果你浏览器里要访问的文件不存在时,会自动路由至web根目录下的index.php进行访问。
当然上面这段话也可以用下面的来代替:

    location / {
        try_files $uri $uri/ /index.php;
    }

完整的配置为:

server{
    listen 80;
    server_name 1.sod90.com app.sod90.com;
    root /a/domains/1.sod90.com/public_html;
    index index.html index.htm index.shtml index.php;

    error_page  404               /404.html;
    #Custom rules Start
        #Custom rules End
        location = /500.html {
        root   /usr/share/nginx/html;
    }

    #location / {
    #    try_files $uri $uri/ /index.php;
    #}

     if (!-e $request_filename) {
          rewrite ^.*$ /city52/index.php last;
     }

    location ~ \.php$ {
        fastcgi_pass   unix:/dev/shm/php.sock;
        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        access_log     /a/apps/nginx/logs/app.sod90.com.access.log main;
    }


    location ~ /\.ht {
        deny  all;
    }
}

注意:上面的try_files完全可以代替rewrite,参见链接
除了加这个重定向之外,conf里不需要再加任何奇奇怪怪的东西。
然后检查CI的config文件里以下三个参数:

$config['base_url'] = 'http://1.abc.com/';
$config['index_page'] = '';
$config['uri_protocol']    = 'REQUEST_URI';

这三个参数比较关键,其中第一个是web根目录对应的域名 ,index_page要为”,不要为默认值 ‘index.php’.
经过以上设置就ok了,url地址里不需要写index.php了。

延伸

现在考虑这种情况,如果一个后台,分支持app和web的,有时候用不同的框架也是在所难免。把所有框架都放在根目录下也不太好看。如果我的CI的根目录不是web的根目录,而是如public_html下的xxx文件夹,此时只需将conf里的try_files语句里路由的/index.php改为/xxx/index.php即可。如下:

    location / {
        try_files $uri $uri/ /xxx/index.php;
    }

再CI的config.php里,写成

$config['base_url'] = 'http://1.abc.com/';

或者:

$config['base_url'] = 'http://app.sod90.com/xxx/';

都是可以的,只要路由对了,就没问题。但是为了保险起见,base_url如后者比较好,然后url里就不要再带index.php了。两者的区别还体现在当使用CI的函数如base_url()时得到的值将会不一样。参考链接

附一个国外比较靠谱点的链接:
http://stackoverflow.com/questions/8182868/nginx-configuration-avoid-codeigniter-rewrite-rules
CI的多目录:http://blog.sina.com.cn/s/blog_6ec2ae900101kbx9.html

补充说明,一般来说conf里如下三句话是关键:

    fastcgi_param  PATH_INFO $fastcgi_path_info;
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    fastcgi_param  PATH_TRANSLATED $document_root$fastcgi_path_info;

但是我的conf里只用了下面一句:

fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
CodeIgniter框架中,获取POST参数可以使用$_POST['key']来获取。此外,CodeIgniter还封装了一个Input类,可以使用$this->input->post('key')来获取POST提交过来的数据。例如,可以使用以下代码来获取POST参数: $key = $_POST['key']; 或者 $key = $this->input->post('key'); 其中,'key'是要获取的POST参数的键名。这样就可以获取到相应的POST参数了。 另外,CodeIgniter还提供了获取GET参数的方法。可以使用$this->input->get('key')来获取GET参数。这样可以方便地获取到URL中的GET参数。 总结起来,CodeIgniter框架中可以通过$_POST['key']、$this->input->post('key')获取POST参数,通过$this->input->get('key')获取GET参数。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [CI框架获取post和get参数_CodeIgniter心得](https://blog.csdn.net/lishk314/article/details/48240607)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [在CodeIgniter中检索JSON POST数据](https://blog.csdn.net/weixin_39954674/article/details/115108581)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值