Yii framework analysis (I) Analysis of the Startup Process of index. php

Source: Internet
Author: User
Tags autoload
1. start the unique Entry Program index of the website. php: $ yiidirname (_ FILE __)... frameworkyii. php; $ configdirname (_ FILE __). protectedconfigmain. php; removethefollowinglinewheninproductionmodedefined (YII_DEBUG) ordefine (YII_DEBUG, true); requi

1. start the unique Entry Program index of the website. php: $ yii = dirname (_ FILE __). /.. /framework/yii. php; $ config = dirname (_ FILE __). /protected/config/main. php; // remove the following line when in production modedefined (YII_DEBUG) or define (YII_DEBUG, true); requi

1. Start

The only website Entry Program index. php:

$yii=dirname(__FILE__).’/../framework/yii.php’;$config=dirname(__FILE__).’/protected/config/main.php’;// remove the following line when in production modedefined(‘YII_DEBUG’) or define(‘YII_DEBUG’,true);require_once($yii);Yii::createWebApplication($config)->run();

The above require_once ($ yii) references the global Yii class to be used later. The Yii class is the full inheritance of the YiiBase class:

class Yii extends YiiBase{}

Global access of the system is implemented through Yii class (that is, YiiBase class), and all Members and methods of Yii class are static.

2. class loading

Yii uses the spl library provided by PHP5 to automatically load classes. At the end of the YiiBase. php file

Spl_autoload_register (array ('yibase', 'autoload '));

Register the static method autoload of the YiiBase class as the class loader. The simple principle of PHP autoload is that when a new object is created or a static member is accessed through the class name, the system passes the class name to the registered Class Loader function, the classloader function finds the corresponding class file based on the class name and includes it.

The following is the autoload method of the YiiBase class:

public static function autoload($className){    // use include so that the error PHP file may appear    if(isset(self::$_coreClasses[$className]))        include(YII_PATH.self::$_coreClasses[$className]);    else if(isset(self::$_classes[$className]))        include(self::$_classes[$className]);    else        include($className.’.php’);}

You can see that the YiiBase static member $ _ coreClasses array contains the file path of the classes used by the Yii system in advance:

private static $_coreClasses=array(    ‘CApplication’ => ‘/base/CApplication.php’,    ‘CBehavior’ => ‘/base/CBehavior.php’,    ‘CComponent’ => ‘/base/CComponent.php’,    …)

Non-coreClasse classes are registered in the $ _ classes array of YiiBase:
Private static $ _ classes = array ();

Other classes need to use Yii: import () to import the class path to PHP include paths, directly
Include ($ className. '. php ')

3. Create CWebApplication

Return to the Yii: createWebApplication ($ config)-> run ();

public static function createWebApplication($config=null){    return new CWebApplication($config);}

Now the autoload mechanism is working.
When the system executes new CWebApplication (),
Include (YII_PATH. '/base/CApplication. php ')

Pass the configuration information array $ config in main. php to the CWebApplication to create an object and execute the run () method of the object to start the framework.

Inheritance relationship of the CWebApplication class

CWebApplication-> CApplication-> CModule-> CComponent

$ Config is first passed to the constructor of 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']));    $this->preinit();    $this->initSystemHandlers();    $this->registerCoreComponents();    $this->configure($config);    $this->attachBehaviors($this->behaviors);    $this->preloadComponents();    $this->init();}

Yii: setApplication ($ this); assigns its instance object to the static member $ _ app of Yii, which can be obtained later through Yii: app.
The following section sets the _ basePath of the CApplication object and points to the proteced directory.

Yii::setPathOfAlias(‘application’,$this->getBasePath());Yii::setPathOfAlias(‘webroot’,dirname($_SERVER['SCRIPT_FILENAME']));

Two System Path aliases are set: application and webroot. You can use the alias to replace the actual full path when importing the system later. The alias configuration is stored in the $ _ aliases array of YiiBase.

$ This-> preinit ();
Pre-initialization. Preinit () is defined in the CModule class without any action.

$ This-> initSystemHandlers () method content:

/*** Initializes the class autoloader and error handlers.*/protected function initSystemHandlers(){    if(YII_ENABLE_EXCEPTION_HANDLER)        set_exception_handler(array($this,’handleException’));    if(YII_ENABLE_ERROR_HANDLER)        set_error_handler(array($this,’handleError’),error_reporting());}

Set the system exception_handler and error_handler to point to the two methods provided by the object itself.

4. Register Core Components

$ This-> registerCoreComponents ();
The Code is as follows:

protected function registerCoreComponents(){    parent::registerCoreComponents();    $components=array(        ‘urlManager’=>array(            ‘class’=>’CUrlManager’,        ),        ‘request’=>array(            ‘class’=>’CHttpRequest’,        ),        ‘session’=>array(            ‘class’=>’CHttpSession’,        ),        ‘assetManager’=>array(            ‘class’=>’CAssetManager’,         ),        ‘user’=>array(            ‘class’=>’CWebUser’,         ),        ‘themeManager’=>array(            ‘class’=>’CThemeManager’,        ),        ‘authManager’=>array(            ‘class’=>’CPhpAuthManager’,        ),        ‘clientScript’=>array(            ‘class’=>’CClientScript’,        ),    );    $this->setComponents($components);}

You have registered several system Components ).
Components is defined and managed in the CModule, mainly including two Arrays

Private $ _ components = array ();
Private $ _ componentConfig = array ();

Each Component is an instance of the IApplicationComponent interface. The componemts instance is stored in the $ _ components array, and the related configuration information is stored in the $ _ componentConfig array. The configuration information includes the class name and attribute settings of Component.

The CWebApplication object registers the following components: urlManager, request, session, assetManager, user, themanager, authManager, and clientScript.

The CWebApplication parent registers the following components: coreMessages, db, messages, errorHandler, securityManager, and statePersister.

Component is a very important thing in YiiPHP. Its feature is that it can be accessed through the _ get () and _ set () Methods of CModule. When Component is registered, it does not create an object instance. Instead, it is created by the CModule (actually Yii: app () when the program is accessed for the first time.

5. Process $ config Configuration

Continue, $ this-> configure ($ config );
Configure () is still in CModule:

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

In fact, each item in the $ config array is passed to the CComponent _ set () method of the parent class of CModule.

public function __set($name,$value){    $setter=’set’.$name;    if(method_exists($this,$setter))        $this->$setter($value);    else if(strncasecmp($name,’on’,2)===0 && method_exists($this,$name))    {        //duplicating getEventHandlers() here for performance        $name=strtolower($name);        if(!isset($this->_e[$name]))            $this->_e[$name]=new CList;        $this->_e[$name]->add($value);    }    else if(method_exists($this,’get’.$name))        throw new CException(Yii::t(‘yii’,'Property “{class}.{property}” is read only.’,            array(‘{class}’=>get_class($this), ‘{property}’=>$name)));    else        throw new CException(Yii::t(‘yii’,'Property “{class}.{property}” is not defined.’,            array(‘{class}’=>get_class($this), ‘{property}’=>$name)));}

Let's take a look:
If (method_exists ($ this, $ setter ))
According to this condition, the basePath, params, modules, import, and components in the $ config array are all passed to the corresponding setBasePath () and setParams () methods for processing.

6. $ config import

Here, import is passed to the CModule's setImport:

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

Processing in Yii: import ($ alias:

Public static function import ($ alias, $ forceInclude = false) {// first checks whether $ alias exists in YiiBase ::$ _ imports [], and the existing direct return, avoid repeated import. If (isset (self ::$ _ imports [$ alias]) // previously imported return self ::$ _ imports [$ alias]; // $ alias class defined, log in to $ _ imports [] and directly return if (class_exists ($ alias, false) return self ::$ _ imports [$ alias] = $ alias; // a class similar to urlManager that has been defined as $ _ coreClasses [] or does not contain. the direct class name is recorded in $ _ imports [], and if (isset (self: $ _ coreClasses [$ alias]) is returned directly | ($ 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 is defined. if ($ className = (string) substr ($ alias, $ pos + 1 ))! = '*' & Class_exists ($ className, false) return self: $ _ imports [$ alias] = $ className; // get the actual path in $ alias and the path is valid if ($ path = self: getPathOfAlias ($ alias ))! = False) {// $ className! = '*', $ ClassName is recorded in $ _ imports [] if ($ className! = '*') {Self: $ _ imports [$ alias] = $ className; if ($ forceInclude) require ($ path. '. php '); else self: $ _ classes [$ className] = $ path. '. php '; return $ className;} // $ alias is 'System. web. * 'to the end of *, add the path to else // a directory {set_include_path (get_include_path () in include_path (). PATH_SEPARATOR. $ path); 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 )));}
7. $ config components

$ Components in the $ config array is passed to the setComponents ($ components) of the CModule)

public function setComponents($components){    foreach($components as $id=>$component)    {        if($component instanceof IApplicationComponent)            $this->setComponent($id,$component);        else if(isset($this->_componentConfig[$id]))            $this->_componentConfig[$id]=CMap::mergeArray($this->_componentConfig[$id],$component);        else            $this->_componentConfig[$id]=$component;    }}

When $ component is an IApplicationComponen instance, the value is assigned directly:
$ This-> setComponent ($ id, $ component ),

public function setComponent($id,$component){    $this->_components[$id]=$component;    if(!$component->getIsInitialized())        $component->init();}

If $ id already exists in _ componentConfig [] (coreComponent registered earlier), add the $ component attribute.
Other component attributes are stored in _ componentConfig.

8. $ config params

This is simple

public function setParams($value){    $params=$this->getParams();    foreach($value as $k=>$v)        $params->add($k,$v);}

Configure complete!

9. attachBehaviors

$ This-> attachBehaviors ($ this-> behaviors );
Empty, no action

Pre-Create component object
$ This-> preloadComponents ();

protected function preloadComponents(){    foreach($this->preload as $id)        $this->getComponent($id);}

GetComponent () determines whether there are $ id instances in the _ components [] array. If not, create a Component Object Based on the configuration in _ componentConfig [$ id, call the init () method of the component and save it to _ components [$ id.

10. init ()

$ This-> init ();

Function: $ this-> getRequest ();
The Reques component is created and initialized.

11. run ()
public function run(){    $this->onBeginRequest(new CEvent($this));    $this->processRequest();    $this->onEndRequest(new CEvent($this));}

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.