CI框架源碼研讀(路由解析)

? ? ? ? ?上篇文章當中我們提到,在CodeIgniter.php中,解析出你訪問的url所對應的controllers和action,然后在調用call_user_func_array()方法,進入到action中,而這里是如何得到這個對應關系的呢,這就是我們現(xiàn)在要討論的內容。

1、CodeIgniter.php

?我們首先來到CodeIgniter.php,發(fā)現(xiàn)這其實是在Router類中實現(xiàn)的,如下源碼:

$RTR =& load_class('Router', 'core', isset($routing) ? $routing : NULL);

$class = ucfirst($RTR->class);

$method = $RTR->method;

2、Router.php

我們進去Router.php中一探究竟,Router類中的構造函數核心是這里:

$this->_set_routing();

_set_routing方法其實核心做這幾步操作:

$_d = $this->config->item('directory_trigger');

$this->set_directory($_d);

$_c = trim($this->config->item('controller_trigger'));

$this->set_class($_GET[$_c]);

$_f = trim($this->config->item('function_trigger'));

$this->set_method($_GET[$_f]);

$this->_parse_routes();

分別從全局變量_GET數組中獲取 directory,class,method,他們的trigger可以在配置文件中配置。當然這是在 enable_query_strings 設置為true的情況下。接下來就進入了最關鍵的方法中_parse_routes方法:

我們在CI的路由配置中,可以如下配置:

$route['products']['put']='product/insert';

就是因為在_parse_routes中的這段代碼:

$http_verb = isset($_SERVER['REQUEST_METHOD']) ? strtolower($_SERVER['REQUEST_METHOD']) : 'cli';

$val = array_change_key_case($val, CASE_LOWER);

if (isset($val[$http_verb])){

$val = $val[$http_verb];}

else{continue;}

HTTP verbs (GET, PUT, POST, DELETE, PATCH) 有這么幾種.而我們在配置中可以這么配置:

$route['product/(:num)']='catalog/product_lookup_by_id/$1';

是因為_parse_routes中的這段代碼:

$key = str_replace(array(':any', ':num'), array('[^/]+', '[0-9]+'), $key);

路由配置中更加可以配置回調函數如:

$route['products/([a-zA-Z]+)/edit/(\d+)']=function($product_type,$id){return'catalog/product_edit/'.strtolower($product_type).'/'.$id;};

是因為有這段代碼:

if ( ! is_string($val) && is_callable($val)){

array_shift($matches);

$val = call_user_func_array($val, $matches);

}

而一般的配置:

else if (strpos($val, ') !== FALSE && strpos($key, '(') !== FALSE){

$val = preg_replace('#^'.$key.'$#', $val, $uri);

}

最后調用了:

$this->_set_request(array_values($this->uri->segments));

_set_request方法當中

$this->set_class($segments[0]);

if (isset($segments[1])){

$this->set_method($segments[1]);

}else{

$segments[1] = 'index';

}

set了class和method,這就得到了我們在開始CodeIgniter.php中所需要的class和method

3、Uri.php

這里要說下這個上面uri的來路:

$uri = implode('/', $this->uri->segments);

我們進入Uri類中查看究竟:

核心的方法是_parse_request_uri,在方法體中,

$uri = parse_url('http://dummy'.$_SERVER['REQUEST_URI']);

$query = isset($uri['query']) ? $uri['query'] : '';

$uri = isset($uri['path']) ? $uri['path'] : '';

return $this->_remove_relative_directory($uri);

主要是用parse_url解析出url當中的path和query,然后進行去除相對路徑的處理。

$this->uri->segments這個成員變量中存儲的就是explode('/', trim($uri, '/') 后的數組,在_set_uri_string方法中賦值。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 因為公司里做商城開發(fā)用的是OpenCart,上級讓我先熟悉這個系統(tǒng),借此機會詳細解讀一下商品管理這一功能(也是為了...
    山有木兮_卿有意閱讀 1,800評論 0 2
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • 把當前目錄作為Root Document只需要這條命令即可:php -S localhost:3300 也可以指定...
    絢爛的時光閱讀 816評論 0 1
  • PHP7 已經出來1年了,PHP7.1也即將和大家見面,這么多好的特性,好的方法,為什么不使用呢,也希望PHP越來...
    夢幻_78af閱讀 2,228評論 1 10
  • 時光逆流 倚靠在山頂那棵老樹旁 借著涼爽的樹蔭 有好多事可想 信手拈來 一朵潔白的花瓣 揮手一灑 流連世間徘徊 起...
    古溪辰閱讀 224評論 0 0

友情鏈接更多精彩內容