ThinkPHP框架完全解析五

第五步:实现Dispatcher,解析url

每一个框架都有其内置的库文件,想要使用的时候,都需要使用include或者是require这两条命令将库文件引入进来。

然而,一个框架库文件是相当多,一下子就使用好几十条include或者是require不仅费时而且还费力,所以我们可以把这些文件定义在一个数组中,然后只要遍历这个数组,然后一一require就可以了。

在tp框架中, ThinkPHP\Mode\common.php就是这么一个文件,这个文件定义了一个二维数组,里面存放了框架所需要使用的文件。

在我们自己实现的框架中,也新建这么一个文件:

<?php

return array(

'core'=>array(

         LIB_PATH.'Think\App.class.php'

)

);

 

因此,在我们的Think.class.php这个文件中的:

require LIB_PATH.'Think\App.class.php';就可以直接替换成一条循环语句,用来将主要文件包含进来。

           $mode=include MODE_PATH.'common.php';

           foreach($mode['core'] as $file){

                if(is_file($file)){

                         include$file;

                }

           }

因此,现在start函数体为:

         staticfunction start(){

                   //注册AUTOLOAD方法

     spl_autoload_register('Think\Think::autoload');

          

           //读取核心类库

           $mode=include MODE_PATH.'common.php';

           foreach($mode['core'] as $file){

                if(is_file($file)){

                         include$file;

                }

           }

          

           App::run();

         }

这样就可以快速地导入我们的框架文件,而不必要去写autoload这个去自动载入,因为使用这个自动载入需要解析,会花费比较长的时间。

现在,转入到我们今天的主题,实现dispatcher这个类。

首先,Think.class.php同一目录下新建一个Dispatcher.class.php这个文件。因为在上一步骤中,我们只是简单地实现url模式,但是却功能简单和不安全,因此,我们将解析url的功能,也就是在上一步骤中app类中exec这个函数中的内容转移到dispatcher这个类中去。将解析功能单独设计成一个类,好处是相当多,因为这样的话,扩展解析功能就比较容易,并且也符合面向对象的设计思想。

<?php

namespace Think;

 

class Dispatcher{

         staticfunction dispatch(){

                   if(isset($_SERVER['PATH_INFO'])){

                            $url=$_SERVER['PATH_INFO'];

                            $str=explode('/',trim($url,'/'));

                   }

                   $MOD=ucfirst(!empty($str[0])?$str[0]:'Home');

                   $CON=ucfirst(!empty($str[1])?$str[1]:'index').'Controller';

                   $ACT=ucfirst(!empty($str[2])?$str[2]:'index');

 

                   define('MODULE_NAME',$MOD);

                   define('CONTROLLER_NAME',$CON);

                   define('ACTION_NAME',$ACT);

         }

}

在这里,不同的是将最后的实例化类变成了定义常量。因为dispatcher这个类的主要功能是解析url,而不是执行url,因此,我们将其定义为常量。这个,在app中的类就可以使用这三个常量了。并且因为idpatcher中解析函数dispatch是一个静态的成员函数,因此我们可以在app::init中运行这个函数,然后再在exec中实例类。

所以当前的app.class.php文件变为:

<?php

namespace Think;

 

class App{

         staticfunction run(){

                   //环境初始化

                   self::init();

                   self::exec();

         }

 

         staticfunction init(){

                   //解析url

                   Dispatcher::dispatch();

         }

        

         staticfunction exec(){

                   //MODULE_NAME都是在dispatcher这个类中被定义的。

                   $namespace=MODULE_NAME.'\\Controller\\';

                   $class=$namespace.CONTROLLER_NAME;

                   //与上一步操作一样,实例化类,并且执行类中的操作

                   $module=new$class;

                   $act=ACTION_NAME;

                   $module->$act();

        

         }

}

在init中需要运行dispatcher这个类,但是包含这个文件的类我们并没有包含,因此我们需要在最开始我们新建的那个common.php这个文件中引入:

<?php

return array(

'core'=>array(

         LIB_PATH.'Think\App.class.php',

         LIB_PATH.'Think\Dispatcher.class.php',

)

);

运行效果如下图:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值