codeigniter路由段错误地使用nginx将破折号转换为下划线

时间:2013-02-03 19:43:53

标签: codeigniter

我遇到一个奇怪的codeigniter 2问题,我在运行nginx 1.3.8的服务器上遇到这个问题。我的uri段中的破折号被作为下划线路由到我的控制器方法:

网址:http://myserver.com/dothis/some-slug-with-dashes/someid

在routes.php中:

$route['^dothis/(.+)/(.+)$'] = "mycontroller/dothis/$1/$2";

在mycontroller.php中

function dothis($slug, $id) {
  // echo $slug shows a value of "some_slug_with_dashes"
}

apache webserver上的相同代码按预期工作(破折号仍为破折号)。

我做了一些跟踪和调试,发现在core / Router.php的_parse_routes()和_set_segments()函数周围发生了问​​题。在Router.php的第389行是

return $this->_set_request(explode('/', $val));

在此处回显$ val的值表明它是/mycontroller/dothis/some-slug-with-dashes/F3e

输出explode()的值显示

Array
(
    [0] => mycontroller
    [1] => dothis
    [2] => some-slug-with-dashes
    [3] => someid
)

将执行追踪到_set_request(),如果我插入一行来输出$segments参数的值:

function _set_request($segments = array())
{
    echo "\n<br/>_set_request() segments: <pre>";print_r($segments);echo "</pre>"; // inserted debug
    $segments = $this->_validate_request($segments);
    ...
}

我得到的调试输出是

_set_request() segments:

Array
(
    [0] => mycontroller
    [1] => dothis
    [2] => some_slug_with_dashes
    [3] => someid
)

如果我回复$this->uri->segments$this->uri->rsegments的其他调试输出,我会得到:

// $this->uri->segments
Array
(
    [0] => dothis
    [1] => some-slug-with-dashes
    [2] => someid
)

// $this->uri->rsegments
Array
(
    [0] => mycontroller
    [1] => dothis
    [2] => some_slug_with_dashes
    [3] => someid
)

我已经检查了我的codeigniter uri允许的字符,这是默认设置。我还检查了nginx和fastcgi参数,它们是基本规则。我还搜索了stackoverflow问题和nginx论坛。在调用_set_request()之前,php显示正确的值似乎很奇怪,但_set_request() param中修改后的值。

有没有人知道或者有什么可能导致这种情况发生的建议?

更新 - 我的nginx配置如下:

nginx.conf:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    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/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  35;

    # limit num of requests from single IP to 5req/s
    limit_req_zone $binary_remote_addr zone=flood:10m rate=5r/s;

    ##########################################################

    # load gzip settings
    include /etc/nginx/conf.d/gzip.conf;

    # load geoip
    include /etc/nginx/conf.d/geoip.conf;

    ##########################################################

    # load all vhosts
    include /etc/nginx/sites-enabled/*.conf;
}

php.conf:

location ~ \.php {
    #fastcgi_pass unix:/tmp/php5-fpm.sock;
    #fastcgi_pass 127.0.0.1:9000;
    fastcgi_pass   php;

    fastcgi_buffers 16 16k;
    fastcgi_buffer_size 32k;

    fastcgi_param  QUERY_STRING       $query_string;
    fastcgi_param  REQUEST_METHOD     $request_method;
    fastcgi_param  CONTENT_TYPE       $content_type;
    fastcgi_param  CONTENT_LENGTH     $content_length;

    fastcgi_param  PATH_INFO          $fastcgi_script_name;
    fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
    fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    fastcgi_param  REQUEST_URI        $request_uri;
    fastcgi_param  DOCUMENT_URI       $document_uri;
    fastcgi_param  DOCUMENT_ROOT      $document_root;
    fastcgi_param  SERVER_PROTOCOL    $server_protocol;

    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
    fastcgi_param  SERVER_SOFTWARE    nginx;

    fastcgi_param  REMOTE_ADDR        $remote_addr;
    fastcgi_param  REMOTE_PORT        $remote_port;
    fastcgi_param  SERVER_ADDR        $server_addr;
    fastcgi_param  SERVER_PORT        $server_port;
    fastcgi_param  SERVER_NAME        $server_name;

    ### SET GEOIP Variables ###
    fastcgi_param GEOIP_COUNTRY_CODE    $geoip_country_code;
    fastcgi_param GEOIP_COUNTRY_CODE3   $geoip_country_code3;
    fastcgi_param GEOIP_COUNTRY_NAME    $geoip_country_name;
    fastcgi_param GEOIP_CITY_COUNTRY_CODE   $geoip_city_country_code;
    fastcgi_param GEOIP_CITY_COUNTRY_CODE3  $geoip_city_country_code3;
    fastcgi_param GEOIP_CITY_COUNTRY_NAME   $geoip_city_country_name;
    fastcgi_param GEOIP_REGION              $geoip_region;
    fastcgi_param GEOIP_CITY                $geoip_city;
    fastcgi_param GEOIP_POSTAL_CODE         $geoip_postal_code;
    fastcgi_param GEOIP_CITY_CONTINENT_CODE $geoip_city_continent_code;
    fastcgi_param GEOIP_LATITUDE            $geoip_latitude;
    fastcgi_param GEOIP_LONGITUDE           $geoip_longitude;
}

我的虚拟主机conf:

upstream php {
    server 127.0.0.1:8004;
}

server {
    listen 80;
    server_name  myserver.com;
    return       301 http://www.myserver.com$request_uri;
}

server {
    server_tokens off;
    listen 80;
    server_name www.myserver.com;

    root /var/www/sites/com.mysite/httpdocs;
    access_log /var/www/sites/com.mysite/logs/access.log;
    error_log /var/www/sites/com.mysite/logs/error.log;

    index index.html index.php;

       location /test {
                auth_basic "Restricted";
                auth_basic_user_file /var/www/sites/com.mysite/.htpasswd;
       }

    location / { 
        # if you're just using wordpress and don't want extra rewrites
        # then replace the word @rewrites with /index.php
        try_files $uri $uri/ @rewrites;
    }

    location @rewrites {
        # Can put some of your own rewrite rules in here
        # for example rewrite ^/~(.*)/(.*)/? /users/$1/$2 last;
        # If nothing matches we'll just send it to /index.php
        rewrite ^ /index.php last;
    }

    # This block will catch static file requests, such as images, css, js
    # The ?: prefix is a 'non-capturing' mark, meaning we do not require
    # the pattern to be captured into $1 which should help improve performance
    #location ~* \.(?:ico|css|js|gif|jpe?g|png|txt|xml)(\?[0-9]+)?$ {
    location ~* \.(?:ico|css|js|gif|jpe?g|png|txt|xml)$ {
        # Some basic cache-control for static files to be sent to the browser
        expires max;
        add_header Pragma public;
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

    include /etc/nginx/conf.d/php.conf;
    include /etc/nginx/conf.d/drop.conf;
}

1 个答案:

答案 0 :(得分:0)

我发现了问题 - 开发人员错误!原来,部署脚本没有正确地从nginx服务器中删除旧的错误的MY_Router.php文件(该文件在本地也不存在,也不在apache安装上)。抱歉,误报 - codeigniter,nginx和php-fpm按预期工作。开发人员(我)不是这种情况。