• 从index.php开始看CodeIgniter的URL映射

    index.php流程
    服务器君一共花费 21.530 ms 进行了 4 次数据库查询,努力地为您提供了这个页面。
    广告很萌的

    CodeIgniter 框架最显著的特征就是 MVC 模式,它的做法就是提取 url 中的“分段”, 映射到某个类的某个方法,从而由该方法来输出最终显示的页面内容。

    尽管 CodeIgniter 已经很精简,但是对于讲解来说,代码还是稍显多了一些。所以这里只是按照 CodeIgniter 的思路,重新走一次框架的流程。注意,可能会与 CodeIgniter 代码有差异,但是思路是一致的。

    我们先来看看入口文件 index.php,先大略了解下。然后再慢慢深入到具体的类与方法的设计。index.php 设计如下,注释已经解释得比较明显了:

    <?php
    /**
     * 框架主入口文件,所有的页面请求均定为到该页面,并根据 url 地址来确定调用合适的方法并显示输出
     */
    
    define('APPPATH', '');
    
    // 自动加载所需的类 
    require('core/Common.php');
    // 加载 core/URI.php 类
    $URI =& load_class('URI');
    // 加载 core/Router.php 类
    $RTR =& load_class('Router');
    // 调用 Router.php 类的 set_routing() 方法,抽取路由信息
    $RTR->set_routing();
    
    // 抽取路由中的 class 名与 method 名
    $class = $RTR->fetch_class();
    $method = $RTR->fetch_method();
    
    // 加载 core/Controller.php 类
    require('core/Controller.php');
    
    function &get_instance() {
    	return CI_Controller::get_instance();
    }
    
    // 根据 class 名加载控制器
    require('controllers/'.$class.'.php');
    
    // new 一个控制器的对象,$class 就是控制器的名
    $CI = new $class();
    
    /*
    echo '<pre>';
    print_r( $URI->rsegments );
    print_r(array(&$CI, $method));
    print_r(array_slice($URI->rsegments, 2));
    echo '</pre>';
    */
    call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 1));
    //call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));
    

    index.php 的大致流程是:

    • require('core/Common.php'); 加载 core/Common.php,这个类具有 function &load_class() 方法,以方便加载其它的类;
    • $URI =& load_class('URI'); 加载 core/URI.php,这个类的作用是分析 URI, 并决定路由,后面后详细介绍;
    • $RTR =& load_class('Router'); 加载 core/Router.php,这个类可以抽取路由的class 名与 method 名。
    • 然后 require('core/Controller.php'); 加载 core/Controller.php,准备加载具体的控制器;
    • $CI = new $class(); 根据加载的控制器,new一个对象;
    • call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 1)); 根据对象创建方法。

    流程似乎也很简单。

    call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 1)); 似乎有点不容易理解:

    call_user_func_array函数也可以调用类内部的方法的:

    Class ClassA   
    {   
    	function bc($b, $c) {   
    		 $bc = $b + $c;   
    	echo $bc;   
    	}   
    }   
    call_user_func_array(array('ClassA','bc'), array("111", "222"));   
      
    //显示 333   
    

    我们可以 print_r( $URI->rsegments ); 看看结果:

    Array
    (
        [0] => welcome
        [1] => nowamagic
    )
    

    再 print_r(array(&$CI, $method)); 看看里面是怎样的:

    Array
    (
        [0] => welcome Object
            (
                [uri] => CI_URI Object
                    (
                        [segments] => Array
                            (
                                [0] => welcome
                                [1] => nowamagic
                            )
    
                        [uri_string] => welcome/nowamagic
                        [rsegments] => Array
                            (
                                [0] => welcome
                                [1] => nowamagic
                            )
    
                    )
    
                [router] => CI_Router Object
                    (
                        [uri] => CI_URI Object
                            (
                                [segments] => Array
                                    (
                                        [0] => welcome
                                        [1] => nowamagic
                                    )
    
                                [uri_string] => welcome/nowamagic
                                [rsegments] => Array
                                    (
                                        [0] => welcome
                                        [1] => nowamagic
                                    )
    
                            )
    
                        [routes] => Array
                            (
                                [default_controller] => home
                                [welcome/nowamagic] => welcome/nowamagic
                            )
    
                        [class] => welcome
                        [method] => nowamagic
                        [default_controller] => home
                    )
    
                [load] => CI_Loader Object
                    (
                        [_ci_model_paths:protected] => Array
                            (
                                [0] => 
                            )
    
                        [_ci_models:protected] => Array
                            (
                            )
    
                    )
    
            )
    
        [1] => nowamagic
    )
    

    看起来东西有点多,但实质上还是保存着一些 uri 和 router 信息而已。从 index.php 我们可以感受到,CI 是如何将 url 映射到具体的方法。

更多 推荐条目

Welcome to NowaMagic Academy!

现代魔法 推荐于 2013-02-27 10:23   

本章最新发布
随机专题
  1. [运维管理] 路由器与交换机 4 个条目
  2. [移动开发] Activity 初步知识 2 个条目
  3. [数据结构] 图的定义 1 个条目
  4. [PHP程序设计] 声明式编程范式 12 个条目
  5. [Python程序设计] Python语言概述 6 个条目
  6. [PHP程序设计] 编程范式初探 3 个条目
  7. [移动开发] 从代码角度去认识 Handler 4 个条目
  8. [Python程序设计] Django与表单 4 个条目
  9. [PHP程序设计] PHP数组的遍历 7 个条目
  10. [运维管理] 防火墙原理与应用 5 个条目
  11. [PHP程序设计] Nginx基本操作释疑 7 个条目
  12. [Python程序设计] Tornado 服务器环境配置 3 个条目
窗口 -- [八点]