国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

yii源碼分析4——非核心類的導(dǎo)入注冊

2019-11-15 02:09:09
字體:
供稿:網(wǎng)友
yii源碼分析4——非核心類的導(dǎo)入注冊

轉(zhuǎn)載請注明:TheViperhttp://m.survivalescaperooms.com/TheViper

在yii源碼分析1中說到spl_autoload_register注冊給定的函數(shù)作為 __autoload 的實(shí)現(xiàn),在這里是autoload().

public static function autoload($className) {        include self::$_coreClasses [$className];     }

實(shí)際上這個autoload()是沒有考慮非核心文件的引入的。比如,在app文件夾經(jīng)常會有自定義的一些重要文件夾,比如'application.utils.*(工具類),'application.filters.*'(過濾類),'application.validators.*'(校驗(yàn)類)等。

在實(shí)際用的時候,是不用一個一個include的,直接new就可以了,yii已經(jīng)幫我們做了include的工作。而這個工作就是在autoload()里面做的。

上面的代碼很顯然沒有考慮非核心文件的引入,這是我的疏忽。

那yii是怎么幫我們引入非核心文件的?

這要從CApplication說起。

abstract class CApplication extends CModule {    public function __construct($config = null) {        if (is_string ( $config ))            $config = require ($config);        Yii::setApplication ( $this );//保存整個app實(shí)例        if (isset ( $config ['basePath'] )) {            $this->setBasePath ( $config ['basePath'] );            unset ( $config ['basePath'] );        } else            $this->setBasePath ( '組件        $this->preloadComponents ();        //這才開始初始化模塊        $this->init ();    }

注意到里面的$this->configure ( $config );,$config是傳入的配置文件,是一個數(shù)組,非核心文件的定義就是在這里面,比如引入工具類文件夾

<?phpreturn array (    'basePath' => dirname ( __FILE__ ) . DIRECTORY_SEPARATOR . '..',    'import' => array (        'application.utils.*'    )    );?> 

然后在父類CModule

    public function configure($config) {        if (is_array ( $config )) {            foreach ( $config as $key => $value )                $this->$key = $value;        }    }

這里yii很"狡猾",它在CModule的父類CComponent中重寫了__set()

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

可以看到,如果CModule中如果有設(shè)置yii指定參數(shù)(比如import)的方法,就會調(diào)用它,而我之前裁剪的時候,把CModule中的setImport()刪掉了。

另外可以看到basePath, params, modules, import, components 是yii保留的參數(shù)名。

    public function setImport($aliases)    {        foreach($aliases as $alias)            Yii::import($alias);    }

然后是YiiBase里面的import()

    public static function import($alias, $forceInclude = false) {        if (isset ( self::$_imports [$alias] )) //是否已經(jīng)存在路徑            return self::$_imports [$alias];                if (class_exists ( $alias, false ) || interface_exists ( $alias, false ))//類是否已經(jīng)定義,針對如urlManager這樣的已定義于$_coreClasses[]的類            return self::$_imports [$alias] = $alias;        if (($pos = strrpos ( $alias, '.' )) === false)         //直接是文件名        {            // try to autoload the class with an autoloader if $forceInclude is true            if ($forceInclude && (Yii::autoload ( $alias, true ) || class_exists ( $alias, true )))                self::$_imports [$alias] = $alias;            return $alias;        }                $className = ( string ) substr ( $alias, $pos + 1 );        $isClass = $className !== '*';        //是否為路徑+類名        if ($isClass && (class_exists ( $className, false ) || interface_exists ( $className, false )))            return self::$_imports [$alias] = $className;        //獲取真實(shí)路徑        if (($path = self::getPathOfAlias ( $alias )) !== false) {            //是否以*結(jié)尾,如application.utils.*            if ($isClass) {                if ($forceInclude) {                    if (is_file ( $path . '.php' ))                        require ($path . '.php');                    else                        throw new CException ( Yii::t ( 'yii', 'Alias "{alias}" is invalid. Make sure it points to an existing PHP file and the file is readable.', array (                                '{alias}' => $alias                         ) ) );                    self::$_imports [$alias] = $className;                } else                    self::$classMap [$className] = $path . '.php';                return $className;            } else             // a directory            {                if (self::$_includePaths === null) {                    self::$_includePaths = array_unique ( explode ( PATH_SEPARATOR, get_include_path () ) );                    if (($pos = array_search ( '.', self::$_includePaths, true )) !== false)                        unset ( self::$_includePaths [$pos] );                }                                array_unshift ( self::$_includePaths, $path );                                if (self::$enableIncludePath && set_include_path ( '.' . PATH_SEPARATOR . implode ( PATH_SEPARATOR, self::$_includePaths ) ) === false)                    self::$enableIncludePath = false;                return self::$_imports [$alias] = $path;            }        }    }

一系列的判斷,最后走到最后的else,將path寫入到$_imports,這時仍然沒有include.

include在autoload()

    public static function autoload($className)    {        // use include so that the error PHP file may appear        if(isset(self::$classMap[$className]))            include(self::$classMap[$className]);        elseif(isset(self::$_coreClasses[$className]))            include(self::$_coreClasses[$className]);        else        {            // include class file relying on include_path            if(strpos($className,'//')===false)  // class without namespace            {                if(self::$enableIncludePath===false)                {                    foreach(self::$_includePaths as $path)                    {                        $classFile=$path.DIRECTORY_SEPARATOR.$className.'.php';                        if(is_file($classFile))                        {                            include($classFile);                            break;                        }                    }                }                else                    include($className.'.php');            }            return class_exists($className,false) || interface_exists($className,false);        }        return true;    }

如果需要include的是非核心文件,那這里的$className只是一個alias,即文件名的前綴。

裁剪的yiihttp://files.VEVb.com/TheViper/framework.zip


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 土默特左旗| 深水埗区| 平安县| 巍山| 孟村| 平南县| 海安县| 万山特区| 佳木斯市| 师宗县| 宁晋县| 五寨县| 凉城县| 长春市| 嵊州市| 苍山县| 许昌县| 鄂伦春自治旗| 平果县| 通化市| 郁南县| 长岭县| 永顺县| 闻喜县| 湛江市| 通海县| 桃园县| 广宗县| 垣曲县| 共和县| 托里县| 恭城| 乐亭县| 依兰县| 三门县| 青龙| 佛坪县| 原阳县| 平乐县| 宣汉县| 林芝县|