nginx 1.3.8 を実行しているサーバーで発生している奇妙な codeigniter 2 の問題があります。URI セグメントのダッシュは、アンダースコアとしてコントローラー メソッドにルーティングされています。
URL: 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 Web サーバー上の同じコードが期待どおりに機能します (ダッシュはダッシュのままです)。
トレースとデバッグを行ったところ、core/Router.php の _parse_routes() および _set_segments() 関数の周りで問題が発生していることがわかりました。Router.php の 389 行目は
return $this->_set_request(explode('/', $val));
ここで $val の値をエコーすると、それが/mycontroller/dothis/some-slug-with-dashes/F3e
.
expand() ショーの値を出力する
Array
(
[0] => mycontroller
[1] => dothis
[2] => some-slug-with-dashes
[3] => someid
)
実行を _set_request() まで追跡し、$segments
paramの値を出力する行を挿入すると、次のようになります。
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;
}