关闭

Yii源码之import小析

标签: 源码yiiphp
292人阅读 评论(0) 收藏 举报
分类:

用过Yii框架的人,一般都知道在Yii的配置里面,有个import参数。这个参数一般可以这样配置:

Yii::setPathOfAlias('docroot', '/data/php/classes');
$config = array(
    ....
    'import' => array(
        'docroot.services.*',
        'docroot.models.*',
    ),
    ...
);

这样配置之后,当有些写好的类放在’/data/php/classes/services/’目录下面,或者放在’/data/php/classes/models’目录下面时,我们也可以在代码中直接使用,不论我们的项目放在哪里。那这是为什么呢?

假设我们现在写的是web应用。那么代码的流程大致如下:
①、Yii::createWebApplication($config)->run();
②、CApplication的构造方法。代码如下:

public function __construct($config=null){
    Yii::setApplication($this);
    // set basePath at early as possible to avoid trouble
    if(is_string($config))
        $config=require($config);
    if(isset($config['basePath'])){
        $this->setBasePath($config['basePath']);
        unset($config['basePath']);
    }
    else
        $this->setBasePath('protected');
    Yii::setPathOfAlias('application',$this->getBasePath());
    Yii::setPathOfAlias('webroot',dirname($_SERVER['SCRIPT_FILENAME']));
    Yii::setPathOfAlias('ext',$this->getBasePath().DIRECTORY_SEPARATOR.'extensions');

    $this->preinit();

    $this->initSystemHandlers();
    $this->registerCoreComponents();//加载核心组件

    $this->configure($config);//加载配置内容
    $this->attachBehaviors($this->behaviors);
    $this->preloadComponents();

    $this->init();
}

③、…..

后续的流程就不讲了,这里就讲一下在CApplication构造方法里面调用的configure方法。这个方法在其父类CModule里面实现。

public function configure($config){
    if(is_array($config)){
        foreach($config as $key=>$value)
            $this->$key=$value;//这里注意了,这里会先调用这个类的魔术方法__set();
    }
}

这段代码很简单,就是遍历config数组,然后调用其魔术方法:

public function __set($name,$value){
    $setter='set'.$name;
    if(method_exists($this,$setter))
        return $this->$setter($value);
    ......
}

在魔术方法里面,会先寻找该类是否存在名为$setter的方法。比如当遍历config,遍历到import时,就会寻找该类中,是否存在名为setimport的成员函数,由于php函数名不区分大小写,所以,发现存在setImport函数,这个函数在CModule中实现。代码如下:

public function setImport($aliases){
    foreach($aliases as $alias)//这里的$alias就是$config['import']
        Yii::import($alias);
}

很简单,就是遍历$config[‘import’],然后调用Yii::import()函数。这个函数就在yii.php里面实现。这个函数主要是做什么事情呢?比如当遍历到
$config[‘import’]的第一个元素,然后将’docroot.services.‘这个值传给import函数。这个函数前面会做几个判断处理,这里我们不用管,一般用不着。然后,它会l调用Yii::getPathOfAlias()这个函数,将’docroot.services.‘转为正确的路径’/data/php/classes/services/*’,最后调用set_include_path()这个方法,将路径设到php的include_path中。这之后,假设在’/data/php/classes/services/’目录下有个’SayHelloService.php’类,当代码中需要的时候,只需要

include('SayHelloService.php');
$sayHello = new SayHelloService();

即可,而不需要给出SayHelloService.php的路径。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:31932次
    • 积分:640
    • 等级:
    • 排名:千里之外
    • 原创:32篇
    • 转载:5篇
    • 译文:1篇
    • 评论:0条
    文章分类
    最新评论