Yii Source Code Analysis 4-non-core class import registration, yii source code. Yii Source Code Analysis 4-non-core class import and registration, yii source code reprint please note: TheViperwww. cnblogs. in yii Source Code Analysis 1, comTheViper mentioned that spl_autoload_register is used to register the given yii Source Code Analysis 4-non-core class import registration, and yii source code
Reprinted please note:TheViper http://www.cnblogs.com/TheViper
In yii Source Code Analysis 1, spl_autoload_register registers the given function as the implementation of _ autoload. here it is autoload ().
public static function autoload($className) { include self::$_coreClasses [$className]; }
In fact, this autoload () does not take into account the introduction of non-core files. For example, app folders often contain custom important folders, such as 'application. utils. * (tool class), 'application. filters. * '(filter class), 'application. validators. * '(verification class.
In actual use, you don't need to include them one by one. you can use new directly. yii has helped us do the include work. This job is done in autoload.
The above code clearly did not consider the introduction of non-core files, which is my negligence.
Then how does yii help us introduce non-core files?
This should start with CApplication.
Abstract class CApplication extends CModule {public function _ construct ($ config = null) {if (is_string ($ config) $ config = require ($ config); Yii :: setApplication ($ this); // save the entire app instance if (isset ($ config ['basepath']) {$ this-> setBasePath ($ config ['basepath']); unset ($ config ['basepath']);} else $ this-> setBasePath ('protected '); // Set the alias, and then you can use application to represent basePath. Yii: setPathOfAli As ('application', $ this-> getBasePath (); // hook, executed during pre-initialization of the module, and implemented by sub-classes. However, the configuration has not been written to the Framework $ this-> preinit (); $ this-> registerCoreComponents (); // The implementation of the parent class $ this-> configure ($ config ); // load the static application component $ this-> preloadComponents (); // this starts to initialize the module $ this-> init ();}
Pay attention to the $ this-> configure ($ config);, $ config is the input configuration file, an array, and the definition of non-core files is here, for example, the introduction of tool folders
dirname ( __FILE__ ) . DIRECTORY_SEPARATOR . '..', 'import' => array ( 'application.utils.*' ) );?>
Then in the parent class CModule
public function configure($config) { if (is_array ( $config )) { foreach ( $config as $key => $value ) $this->$key = $value; } }
Here yii is "tricky". It overwrites _ set () in CModule's parent class CComponent ()
public function __set($name,$value) { $setter='set'.$name; if(method_exists($this,$setter)) return $this->$setter($value); else.... }
As you can see, if the CModule contains a method that sets the yii specified parameter (such as import), it will be called, and I deleted the setImport () in the CModule when cropping.
In addition, we can see that basePath, params, modules, import, and components are the parameter names reserved by yii.
public function setImport($aliases) { foreach($aliases as $alias) Yii::import($alias); }
Then the import () in YiiBase ()
Public static function import ($ alias, $ forceInclude = false) {if (isset (self ::$ _ imports [$ alias]) // whether the path "return self:" already exists :: $ _ imports [$ alias]; if (class_exists ($ alias, false) | interface_exists ($ alias, false) // whether the class has been defined, return self: $ _ imports [$ alias] = $ alias for classes like $ _ coreClasses [] such as urlManager; if ($ pos = strrpos ($ alias ,'. ') = false) // directly indicates the file name {// try to autoload the class wit H 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! = '*'; // Whether it is a path + class name if ($ isClass & (class_exists ($ className, false) | interface_exists ($ className, false ))) return self: $ _ imports [$ alias] = $ className; // Obtain the true path if ($ path = self: getPathOfAlias ($ alias ))! = False) {// whether to end with *, such as 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 ;}}}
A series of judgments, finally to the final else, write the path to $ _ imports, then there is still no include.
Include in 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; }
If you need to include non-core files, $ className here is just an alias, that is, the prefix of the file name.
Cropped yii http://files.cnblogs.com/TheViper/framework.zip
If you think the content of this article is helpful to you, you can reward me:
For details about "register", please specify TheViperhttp: // www.cnblogs.com/TheViper. in yii Source Code Analysis 1, spl_autoload_register is used to register a given domain...