


Yii Framework Analysis (3) - Class Loading Mechanism and Management, Configuration, Access and Creation of Application Components
The entry script of the Yii application references the Yii class. The definition of the Yii class:
class Yii extends YiiBase { }
In the application created by yiic, the Yii class is just the "vest" of the YiiBase class. We can also customize our own according to our needs. Yii category.
Yii (i.e. YiiBase) is a "helper class" that provides static and global access to the entire application.
Several static members of the Yii class:
$_aliases: stores the real paths corresponding to system aliases
$_imports:
$_classes:
$_includePaths php include paths
$_app: CWebApplication object, accessed through Yii::app()
$_logger: System log object
$_app object is created by Yii::createWebApplication() method.
Class automatic loading
Yii is based on the autoload mechanism of php5 to provide the automatic loading function of classes. The automatic loader is the static method autoload() of the YiiBase class.
When the program uses new to create an object or access a static member of a class, PHP passes the class name to the class loader, and the class loader completes the include of the class file.
The autoload mechanism implements the "on-demand import" of classes, which means that the system includes the class file only when it accesses the class.
The static member $_coreClasses of the YiiBase class pre-stores Yii's own core class name and the corresponding class file path. Classes used in other Yii applications can be imported using Yii::import(). Yii::import() stores the single class and corresponding class files in $_classes, and adds the path represented by the * wildcard character to php include_path. . Class files or directories imported by Yii::import() are recorded in $_imports to avoid multiple imports.
/* Yii::import() * $alias: 要导入的类名或路径 * $forceInclude false:只导入不include类文件,true则导入并include类文件 */ public static function import($alias,$forceInclude=false) { // 先判断$alias是否存在于YiiBase::$_imports[] 中,已存在的直接return, 避免重复import。 if(isset(self::$_imports[$alias])) // previously imported return self::$_imports[$alias]; // $alias类已定义,记入$_imports[],直接返回 if(class_exists($alias,false) || interface_exists($alias,false)) return self::$_imports[$alias]=$alias; // 已定义于$_coreClasses[]的类,或名字中不含.的类,记入$_imports[],直接返回 if(isset(self::$_coreClasses[$alias]) || ($pos=strrpos($alias,’.'))===false) // a simple class name { self::$_imports[$alias]=$alias; if($forceInclude) { if(isset(self::$_coreClasses[$alias])) // a core class require(YII_PATH.self::$_coreClasses[$alias]); else require($alias.’.php’); } return $alias; } // 产生一个变量 $className,为$alias最后一个.后面的部分 // 这样的:’x.y.ClassNamer’ // $className不等于 ‘*’, 并且ClassNamer类已定义的,????? ClassNamer’ 记入 $_imports[],直接返回 if(($className=(string)substr($alias,$pos+1))!==’*’ && (class_exists($className,false) || interface_exists($className,false))) return self::$_imports[$alias]=$className; // $alias里含有别名,并转换真实路径成功 if(($path=self::getPathOfAlias($alias))!==false) { // 不是以*结尾的路径(单类) if($className!==’*') { self::$_imports[$alias]=$className; if($forceInclude) require($path.’.php’); else // 类名与真实路径记入$_classes数组 self::$_classes[$className]=$path.’.php’; return $className; } // $alias是’system.web.*’这样的已*结尾的路径,将路径加到include_path中 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); set_include_path(‘.’.PATH_SEPARATOR.implode(PATH_SEPARATOR,self::$_includePaths)); return self::$_imports[$alias]=$path; } } else throw new CException(Yii::t(‘yii’,'Alias “{alias}” is invalid. Make sure it points to an existing directory or file.’,array(‘{alias}’=>$alias))); }
Then take a look at the processing of the YiiBase::autoload() function:
public static function autoload($className) { // $_coreClasses中配置好的类直接引入 if(isset(self::$_coreClasses[$className])) include(YII_PATH.self::$_coreClasses[$className]); // $_classes 中登记的单类直接引入 else if(isset(self::$_classes[$className])) include(self::$_classes[$className]); else { // 其他的认为文件路径以记入 include_path 里,以$className.’.php’直接引入 include($className.’.php’); return class_exists($className,false) || interface_exists($className,false); } return true; }
The classes or paths in the import item in the system configuration file will be automatically imported during script startup. For classes that need to be imported into individual classes in user applications, the Yii::import() statement can be added before the class definition.
Application component management
As mentioned earlier, Yii's CComponent class provides access interfaces to component properties, events, and behaviors, and CComponent's subclass CModule also provides application components. management.
The application component must be an instance of the IApplicationComponent interface and needs to implement the init() and getIsInitialized() methods of the interface. init() will be automatically called after applying component initialization parameters.
Yii's own functional modules are provided through application components, such as the common Yii::app()->user, Yii::app()->request, etc. Users can also define application components.
As the parent class of the Yii::app() object (CWebApplication), CModule provides complete component life cycle management, including component creation, initialization, object storage, etc.
Each application component is identified by a string name and accessed through the __get() method of the CModule class.
The $_components[] member of the CModule class stores the object instance of the application component ($name => $object), and $_componentConfig[] stores the class name and initialization parameters of the application component.
When using an application component, first set the class name and initialization parameters of the component in $_componentConfig. When accessing the component for the first time, CModule will automatically create an application component object instance and initialize the given parameters. Then the init() method of the application component is called.
Yii::app() object's class CWebApplication and its parent class CApplication are pre-configured with application components used by the system itself: urlManager, request, session, assetManager, user, themeManager, authManager, clientScript, coreMessages, db, messages, errorHandler, securityManager, statePersister.
We can modify the parameters of the system application components or configure new application components in the components project of the system configuration file.
CModule is not responsible for the creation of application component instances, but is completed by the Yii::createComponent() static method.
The parameter $config of createComponent() can be a string of class name or an array storing class name and initialization parameters.
Configuration of application components
The configuration of application components is stored in the components item in the system $config variable (config/main.php):
// application components ‘components’=>array( ‘log’=>array( ‘class’=>’CLogRouter’, ‘routes’=>array( array( ‘class’=>’CFileLogRoute’, ‘levels’=>’error, warning’, ), ), ), ‘user’=>array( // enable cookie-based authentication ‘allowAutoLogin’=>true, ), ),
$config The components items are processed in the constructor of CApplication:
$this->configure($config);
The processing of the configure() function is very simple:
public function configure($config) { if(is_array($config)) { foreach($config as $key=>$value) $this->$key=$value; } }
Each item in $config is passed as an attribute to the setXXX() attribute setting method of the $_app object, where the 'components' item is processed by setComponents(), the parent class of CModule in CWebApplication.
setComponents() stores the class name and initialization parameters in the 'components' item into $_componentConfig[]:
public function setComponents($components) { // $config 里的’components’每一项 foreach($components as $id=>$component) { if($component instanceof IApplicationComponent) $this->setComponent($id,$component); // $_componentConfig里已经存在配置,合并$component else if(isset($this->_componentConfig[$id])) $this->_componentConfig[$id]=CMap::mergeArray($this->_componentConfig[$id],$component); // 在$_componentConfig里新建项目 else $this->_componentConfig[$id]=$component; } }
Access to application components
CModule类重载了CComponent的__get()方法,优先访问应用组件对象。
public function __get($name) { if($this->hasComponent($name)) return $this->getComponent($name); else return parent::__get($name); }
hasComponent() 判断$_components[]中是否已存在组件实例,或$_componentConfig[]中存在组件配置信息。
public function hasComponent($id) { return isset($this->_components[$id]) || isset($this->_componentConfig[$id]); }
getComponent() 判断组件实例已经存在于$_components[]中,则直接返回对象。
否则根据$_componentConfig[]里的组件配置数据调用 Yii::createComponent() 来创建组件,并将对象存入$_components[]中然后返回。
public function getComponent($id,$createIfNull=true) { if(isset($this->_components[$id])) return $this->_components[$id]; else if(isset($this->_componentConfig[$id]) && $createIfNull) { $config=$this->_componentConfig[$id]; unset($this->_componentConfig[$id]); if(!isset($config['enabled']) || $config['enabled']) { Yii::trace(“Loading \”$id\” application component”,’system.web.CModule’); unset($config['enabled']); $component=Yii::createComponent($config); $component->init(); return $this->_components[$id]=$component; } } }
应用组件的创建
Yii::createComponent() 来完成应用组件的创建
public static function createComponent($config) { if(is_string($config)) { $type=$config; $config=array(); } else if(isset($config['class'])) { $type=$config['class']; unset($config['class']); } else throw new CException(Yii::t(‘yii’,'Object configuration must be an array containing a “class” element.’)); if(!class_exists($type,false)) $type=Yii::import($type,true); if(($n=func_num_args())>1) { $args=func_get_args(); if($n===2) $object=new $type($args[1]); else if($n===3) $object=new $type($args[1],$args[2]); else if($n===4) $object=new $type($args[1],$args[2],$args[3]); else { unset($args[0]); $class=new ReflectionClass($type); // Note: ReflectionClass::newInstanceArgs() is available for PHP 5.1.3+ // $object=$class->newInstanceArgs($args); $object=call_user_func_array(array($class,’newInstance’),$args); } } else $object=new $type; foreach($config as $key=>$value) $object->$key=$value; return $object; }
以上就是Yii框架分析(三)——类加载机制及应用组件的管理、配置、访问、创建的内容,更多相关内容请关注PHP中文网(www.php.cn)!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

Notepad++7.3.1
Easy-to-use and free code editor

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool