在上一課中,我們實現了簡單的根據 URI 執行某個類的某個方法。但是這種映射沒有擴展性,對於一個成熟易用的框架肯定是行不通的。那么,我們可以讓 框架的用戶 通過自定義這種轉換來控制,用 CI 的術語就是 ”路由“。
1. 路由具體負責做什么的?
舉個例子,上一課中 http://localhost/learn-ci/index.php/welcome/hello, 會執行 Welcome類的 hello 方法,但是用戶可能會去想去執行一個叫 welcome 的函數,並傳遞 'hello' 為參數。
更實際一點的例子,比如你是一個產品展示網站, 你可能想要以如下 URI 的形式來展示你的產品,那么肯定就需要重新定義這種映射關系了。
example.com/product/1/
example.com/product/2/
example.com/product/3/
example.com/product/4/
2. 實現一個簡單的路由
1) 新建 routes.php 文件,並在里面定義一個 routes 數組,routes 數組的鍵值對即表示路由映射。比如
1 /** 2 * routes.php 自定義路由 3 */ 4 5 $routes['default_controller'] = 'home'; 6 7 $routes['welcome/hello'] = 'welcome/saysomething/hello';
2) 在 index.php 中包含 routes.php
1 include('routes.php');
3) 兩個路由函數,分析路由 parse_routes ,以及映射到具體的方法上去 set_request
1 function parse_routes() { 2 global $uri_segments, $routes, $rsegments; 3 4 $uri = implode('/', $uri_segments); 5 6 if (isset($routes[$uri])) { 7 $rsegments = explode('/', $routes[$uri]); 8 9 return set_request($rsegments); 10 } 11 } 12 13 function set_request($segments = array()) { 14 global $class, $method; 15 16 $class = $segments[0]; 17 18 if (isset($segments[1])) { 19 $method = $segments[1]; 20 } else { 21 $method = 'index'; 22 } 23 }
4) 分析路由,執行路由后的函數,通過 call_user_func_array() 函數
1 parse_routes(); 2 3 $CI = new $class(); 4 5 call_user_func_array(array(&$CI, $method), array_slice($rsegments, 2));
5) 給 Welcome 類添加 saysomething 函數做測試
1 class Welcome { 2 3 function hello() { 4 echo 'My first Php Framework!'; 5 } 6 7 function saysomething($str) { 8 echo $str.", I'am the php framework you created!"; 9 } 10 }
測試結果: 訪問 http://localhost/learn-ci/index.php/welcome/hello ,可以看到與第一課不同的輸出結果
hello, I'am the php framework you created!
