Yii Framework Analysis (III)-class loading mechanism and management, configuration, access, and creation of application components

Source: Internet
Author: User
Yii Framework Analysis (III)-class loading mechanism and management, configuration, access, and creation of application components

The Yii application portal script references the Yii class, Yii class definition:

class Yii extends YiiBase{}

In an application created by yiic, the Yii category is only the "vest" of the YiiBase category. you can also customize your Yii category as needed.

Yii (that is, YiiBase) is a "helper class" that provides static and global access portals for the entire application.

Several static members of Yii:
$ _ Aliases: stores the real path corresponding to the system alias
$ _ Imports:
$ _ Classes:
$ _ IncludePaths php include paths
$ _ App: CWebApplication object, accessed through Yii: app ()
$ _ Logger: System Log object
$ _ The app object is created by the Yii: createWebApplication () method.

Class automatically loaded

Yii provides automatic class loading based on the php5 autoload mechanism. the automatic loader is the static method autoload () of the YiiBase class ().

When the program uses new to create objects or access static members of the 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 "import on demand" of the class, that is, the files that include the class only when the system accesses the class.

The YiiBase static member $ _ coreClasses pre-stores the Yii core class name in the corresponding class file path. The classes used in other Yii applications can be imported using Yii: import (). Yii: import () stores the single class and corresponding class files in $ _ classes, add the path represented by * wildcard to php include_path. The class files or directories imported by Yii: import () are recorded in $ _ imports to avoid multiple imports.

/* Yii: import () * $ alias: name or path of the class to be imported * $ forceInclude false: import only non-include class files, true: import and include the class file */public static function import ($ alias, $ forceInclude = false) {// first checks whether $ alias exists in YiiBase :: $ _ imports [] already exists direct return to avoid repeated import. If (isset (self ::$ _ imports [$ alias]) // previously imported return self ::$ _ imports [$ alias]; // $ alias class defined, logs $ _ imports [] and returns if (class_exists ($ alias, false) | interface_exists ($ alias, false) return self :: $ _ imports [$ alias] = $ alias; // The class defined in $ _ coreClasses [], or the name does not include. is recorded in $ _ imports [], and if (isset (self: $ _ coreClasses [$ alias]) is directly returned | ($ 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;} // generates a variable $ className, which is the last of $ alias. the following part // is like this: 'X. y. classNamer '// $ className is not equal to' * ', and the ClassNamer class has been defined ,????? ClassNamer is recorded in $ _ imports [] and returns if ($ className = (string) substr ($ alias, $ pos + 1) directly ))! = '*' & (Class_exists ($ className, false) | interface_exists ($ className, false) return self :: $ _ imports [$ alias] = $ className; // $ alias contains aliases and converts them to true paths if ($ path = self: getPathOfAlias ($ alias ))! = False) {// path not ending with * (single class) if ($ className! = '*') {Self: $ _ imports [$ alias] = $ className; if ($ forceInclude) require ($ path. '. php '); else // the class name and real path are recorded in the $ _ classes array self ::$ _ classes [$ className] = $ path. '. php '; return $ className;} // $ alias is 'system. web. * 'to the end of *, add the path to 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 let's take a look at the processing of the YiiBase: autoload () function:

Public static function autoload ($ className) {// $ _ if (isset (self ::$ _ coreClasses [$ className]) include (YII_PATH.self:: $ _ coreClasses [$ className]); // $ _ directly introduces else if (isset (self ::$ _ classes [$ className]) to the single class registered in classes. include (self: $ _ classes [$ className]); else {// Other file paths that are considered to be in include_path, with $ className. '. php 'directly introduces include ($ className. '. php '); return class_exists ($ className, false) | interface_exists ($ className, false);} return true ;}

The classes or paths in the import items in the system configuration file will be automatically imported during script startup. The Yii: import () statement can be added before the class definition of some classes in your application.

Application Component Management

The CComponent class of Yii provides access interfaces for attributes, events, and behaviors of components, while the CModule subclass of CComponent provides management of application components.

The application component must be an instance of the IApplicationComponent interface, and the init () and getIsInitialized () methods of the interface must be implemented. Init () is automatically called after application component initialization parameters.

The functional modules of Yii are provided through application components, such as common Yii: app ()-> user, Yii: app ()-> request. You can also define application components.

As the parent class of the Yii: app () object (CWebApplication), CModule provides complete component lifecycle management, including component creation, initialization, and object storage.

Each application component is identified by a string and accessed through the _ get () method of the CModule class.

The $ _ components [] member of the CModule class stores the object instance ($ name => $ object) of the application component, and the class name and initialization parameters of the application component in $ _ componentConfig.

When using the application component, set the class name and initialization parameters of the component in $ _ componentConfig. when accessing the component for the first time, the CModule automatically creates an application Component Object instance, initializes the given parameters, and then calls the init () method of the application component.

Yii: CWebApplication of the app () object and its parent CApplication are pre-configured with the application components used by the system: urlManager, request, session, assetManager, user, themanager, authManager, clientScript, coreMessages, db, messages, errorHandler, securityManager, statePersister.

You can modify the parameters of system application components or configure new application components in the components project of the system configuration file.

The CModule is not responsible for creating application component instances, but is completed by the Yii: createComponent () static method.

The createComponent () parameter $ config can be a class name string or an array that stores the class name and initialization parameters.

Application component configuration

The configuration of the application component is stored in the components item of 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,    ),),

The components item in $ config is processed in the CApplication constructor:

$ This-> configure ($ config );

The configure () function is easy to process:

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

Each item in $ config is passed as a property to the setXXX () attribute setting method of the $ _ app object. the 'components' item is processed by setComponents (), the parent class of the CModule of the CWebApplication.

SetComponents () stores the class name and initialization parameters in the 'components' item in $ _ componentConfig:

Public function setComponents ($ components) {// 'components' in $ config each item foreach ($ components as $ id => $ component) {if ($ component instanceof IApplicationComponent) $ this-> setComponent ($ id, $ component); // configuration already exists in $ _ componentConfig, merge $ component else if (isset ($ this-> _ componentConfig [$ id]) $ this-> _ componentConfig [$ id] = CMap :: mergeArray ($ this-> _ componentConfig [$ id], $ component ); // create a project else $ this-> _ componentConfig [$ id] = $ component;} in $ _ componentConfig ;}}
Application component access

The CModule class reloads the _ get () method of CComponent and preferentially accesses the application component object.

public function __get($name){    if($this->hasComponent($name))        return $this->getComponent($name);    else        return parent::__get($name);}

HasComponent () determines whether a component instance exists in $ _ components [], or whether component configuration information exists in $ _ componentConfig.

public function hasComponent($id){    return isset($this->_components[$id]) || isset($this->_componentConfig[$id]);}

If getComponent () determines that the component instance already exists in $ _ components [], an object is directly returned.
Otherwise, you can call Yii: createComponent () to create a component based on the component configuration data in $ _ componentConfig [], save the object to $ _ components [], and return the result.

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;        }    }}
Application component creation

Yii: createComponent () to create application components

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;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.