首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

CodeIgniter URI 類 _fetch_uri_string() 核心邏輯解析

     編輯:PHP 綜合知識

system/core/URI.php 中的 _fetch_uri_string() 是 CodeIgniter 解析當前請求 URI 的核心私有方法,支援 5 種偵測策略 (AUTO、PATH_INFO、QUERY_STRING、REQUEST_URI、ORIG_PATH_INFO)。本文詳細剖析其流程、各策略適用場景與常見配置陷阱。

一、配置項 $config['uri_protocol']

$config['uri_protocol'] = 'AUTO'; // 預設
// 可選值:
// 'AUTO'            → 依序嘗試下列 4 種
// 'PATH_INFO'       → $_SERVER['PATH_INFO']
// 'QUERY_STRING'    → $_SERVER['QUERY_STRING']
// 'REQUEST_URI'     → $_SERVER['REQUEST_URI']
// 'ORIG_PATH_INFO'  → $_SERVER['ORIG_PATH_INFO'] (IIS/特定 CGI)

二、_fetch_uri_string() 完整流程圖解

protected function _fetch_uri_string() {
    $protocol = $this->config->item('uri_protocol');

    // 1. CLI 模式專屬處理
    if (php_sapi_name() === 'cli') {
        return $this->_parse_cli_args();
    }

    // 2. 非 AUTO:直接呼叫對應策略
    if ($protocol !== 'AUTO') {
        return $this->_detect_uri($protocol);
    }

    // 3. AUTO 模式:依優先序輪詢
    $methods = ['REQUEST_URI', 'PATH_INFO', 'QUERY_STRING', 'ORIG_PATH_INFO'];
    foreach ($methods as $method) {
        $uri = $this->_detect_uri($method);
        if ($uri !== '') return $uri;
    }
    return '';
}

三、各策略詳細實作 _detect_uri()

1. REQUEST_URI (最常用、Nginx/Apache mod_rewrite 預設)

$uri = $_SERVER['REQUEST_URI'];
// 移除 query string
if (($pos = strpos($uri, '?')) !== FALSE) {
    $uri = substr($uri, 0, $pos);
}
// 移除前導 /index.php (若存在)
$uri = preg_replace('~^' . preg_quote($this->config->item('index_page'), '~') . '~', '', $uri);
return $uri;

適用: 幾乎所有現代 PHP-FPM + Nginx/Apache 環境。

2. PATH_INFO (傳統 CGI、舊版 Apache)

$path = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
if (trim($path, '/') !== '' && $path !== '/' . SELF) {
    return $path;
}

注意: 需 Web Server 設定 cgi.fix_pathinfo=1。

3. QUERY_STRING (舊式 ?/controller/method 模式)

$path = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
if (trim($path, '/') !== '') {
    return $path;
}

對應網址:example.com/?/controller/method 或 example.com/index.php?/controller/method。

4. ORIG_PATH_INFO (IIS / 特定 FastCGI)

$path = isset($_SERVER['ORIG_PATH_INFO']) ? $_SERVER['ORIG_PATH_INFO'] : @getenv('ORIG_PATH_INFO');
// 同 PATH_INFO 處理

5. CLI 參數解析 _parse_cli_args()

$args = array_slice($_SERVER['argv'], 1); // 移除 script name
return $args ? '/' . implode('/', $args) : '';

執行 php index.php controller method arg1 arg2 → /controller/method/arg1/arg2。

四、常見配置問題與解決方案

現象原因解決
URL 顯示 index.php 且 404Nginx 未正確 rewrite、uri_protocol 不匹配設定 REQUEST_URI + 正確 rewrite 規則
參數包含 ?、& 導致路由錯誤QUERY_STRING 策略將完整 query string 當 URI改用 REQUEST_URI 或 PATH_INFO
子目錄部署 (example.com/sub/)REQUEST_URI 含 /sub/ 前綴在 config.php 設定 $config['base_url']、$config['index_page'] = ''
IIS 環境 404PATH_INFO 未啟用設定 uri_protocol = 'ORIG_PATH_INFO' 或啟用 IIS URL Rewrite

五、最佳實踐建議

  1. 生產環境鎖定策略: 不要用 AUTO,明確設定 $config['uri_protocol'] = 'REQUEST_URI'; 避免輪詢開銷與歧義。
  2. 隱藏 index.php (Nginx):
location / {
    try_files $uri $uri/ /index.php$is_args$args;
}
  1. Apache .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
  1. 子目錄部署: $config['base_url'] = 'https://example.com/sub/'; $config['uri_protocol'] = 'REQUEST_URI';。
  2. 除錯技巧: 在 Controller 建構子 log_message('debug', 'URI: ' . $this->uri->uri_string()); 觀察實際解析結果。

六、原始碼關鍵屬性對照

屬性用途
$this->uri_string原始 URI 字串 (如 controller/method/arg)
$this->segments分段陣列 (索引從 1 開始)
$this->rsegments重新索引陣列 (從 0 開始,供路由使用)
$this->keyvalURI 參數快取
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved