我在运行 nginx 1.3.8 的服务器上遇到了一个奇怪的 codeigniter 2 问题。我的 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 网络服务器上的相同代码按预期工作(破折号仍然是破折号)。
我做了一些跟踪和调试,发现问题出现在 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 论坛。php 在调用之前显示正确的值_set_request()
但在_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;
}
我的虚拟主机配置:
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;
}