YII source code analysis (-) and yii source code analysis

Source: Internet
Author: User

YII source code analysis (-) and yii source code analysis

As the first show of source code analysis, I chose yii (reading as an example, not as an example). I won't say much about its praise, but I will go straight into the topic. Prepare materials first. We recommend that you download the latest yii source code package (1.1.15) from the official website.

In demos, the simplest application-helloworld. is to use the yii framework to output a sentence: "hello world ";

I will start with it and analyze the components that the framework needs to go through to execute a minimum process and its running process.

First, read from a single entry file. (The source code is generally analyzed from the call point)

Index. php->

// Include Yii bootstrap file

// Introduce the Startup File

Require_once (dirname (_ FILE _). '/.../../framework/yii. php ');

 

Yii. php->

// YiiBase is a helper class serving common framework functionalities.

// YiiBase is a helper class that serves the entire framework. Many important constants are defined here.

Require (dirname (_ FILE _). '/YiiBase. php ');

// Register the automatic loading class

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

// Import Interface Class

Require (YII_PATH. '/base/interfaces. php ');

// Start the application

Yii: createWebApplication ()-> run ();

The Code seems to end here, and the content of the page also comes out, but we have no idea what the framework has done. Therefore, we need to break down this step and expose the details.

Yii: createWebApplication ()-> run () can be divided into three parts.

What is Yii?

From yii. php, you can find this line of code class Yii extends YiiBase.

It indicates that it is the inheritance class of YiiBase, and the extension of the author is left blank. Therefore, Yii is a reference of YiiBase. Therefore, the static createWebApplication method also needs to be searched in YiiBase.

In YiiBase. php, you can easily find this method:

Public static function createWebApplication ($ config = null)

{

Return self: createApplication ('cwebapplication', $ config );

}

It passes the task to createApplication:

Public static function createApplication ($ class, $ config = null)

{

Return new $ class ($ config );

}

In combination, createWebApplication () is return new CWebApplication ($ config );

Where is the CWebApplication class? How is it introduced?

With a series of problems, I went back to YiiBase. php

The edge defines a long array, you can find:

'Webapplication' => '/web/CWebApplication. php', which is a member of the automatic loading class.

For details about how it is automatically loaded, refer to the related documents of spl_autoload_register.

 

We continue to dig deep into the CWebApplication. Open the/web/CWebApplication. php file.

Return new CWebApplication ($ config); based on my experience, a new constructor is usually used, but I have not found its constructor, it must be in its parent class, so I went up to find out, class CWebApplication extends CApplication was indeed discovered by me, which is the same as digging Loach, so I had to follow the clues for a little bit, be patient.

 

CApplication really has constructor. The Code is as follows:

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']));                   if(isset($config['extensionPath']))                   {                            $this->setExtensionPath($config['extensionPath']);                            unset($config['extensionPath']);                   }                   else                            Yii::setPathOfAlias('ext',$this->getBasePath().DIRECTORY_SEPARATOR.'extensions');                   if(isset($config['aliases']))                   {                            $this->setAliases($config['aliases']);                            unset($config['aliases']);                   }

 

// All of the above can be regarded as initialization, and class reference, alias, path or something can be set.

$ This-> preinit (); // No usage is found for the moment. It is estimated that it will be reserved for later extension.

 

$ This-> initSystemHandlers (); // sets error handling

$ This-> registerCoreComponents (); // register the Core Component

 

$ This-> configure ($ config); // extend the attributes of the class through the configuration file. If it is null, nothing will be done.

$ This-> attachBehaviors ($ this-> behaviors );

$ This-> preloadComponents ();

 

$ This-> init ();

}

Some methods under $ this cannot be found in the current class, because they may come from the parent class. The simplest method is ctrl + f, if not, go to the declaration of the class to view it:

Abstract class CApplication extends CModule

It is obvious that you want to enter the CModule. If you still cannot find the desired method at this time, proceed to the previous process:

Abstract class CModule extends CComponent

Until class CComponent

This is the old nest of these guys. You can also see from the comments in the Code:

CComponent is the base class for all components

It indicates that my idea is correct. Yes, it is a base class.

Through code, we can find that our current application, because many parameters are empty, many logics are skipped directly.

The content of $ this is also clear. Let's look back.

Return new CWebApplication ($ config)-> run ();

Through the previous layer-by-layer analysis, the run method is also very easy to find. In CApplication:

public function run()         {                   if($this->hasEventHandler('onBeginRequest')){                            $this->onBeginRequest(new CEvent($this));                   }                    register_shutdown_function(array($this,'end'),0,false);                   $this->processRequest();                     if($this->hasEventHandler('onEndRequest')){                            $this->onEndRequest(new CEvent($this));                   }          }

 

Focus on: $ this-> processRequest (); because the previous and subsequent sections are related to the registration event, the current condition cannot be executed.

Abstract public function processRequest (); this method is abstract in the current class, so it must be implemented in its subclass. Go back to CWebApplication: public function processRequest () {if (is_array ($ this-> catchAllRequest) & isset ($ this-> catchAllRequest [0]) {$ route = $ this-> catchAllRequest [0]; foreach (array_splice ($ this-> catchAllRequest, 1) as $ name => $ value) $ _ GET [$ name] = $ value;} else $ route = $ this-> getUrlManager ()-> parseUrl ($ this-> getRequest ()); $ this-> runController ($ route );}

 

 

Focus on $ this-> runController ($ route );

 

public function runController($route)         {                   if(($ca=$this->createController($route))!==null)                   {                            list($controller,$actionID)=$ca;                             $oldController=$this->_controller;                            $this->_controller=$controller;                            $controller->init();                            $controller->run($actionID);                            $this->_controller=$oldController;                   }                   else                            throw new CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".',                                     array('{route}'=>$route===''?$this->defaultController:$route)));         }

 

 

We should note that there are only two lines of code:

$ Controller-> init ();

$ Controller-> run ($ actionID );

The $ controller here can be viewed through the createController, that is, the default controller Sitecontroller. php.

The Action is the index. How did you see it? Haha, can I just echo or var_dump somewhere I can't guess? Such a simple logic is not ready for the appearance of xdebug.

Obviously, init has nothing to do. Let's see what run has done.

Sitecontroller does not have the run method, but needs to be searched in its parent class.

Class SiteController extends CController

 

This method is available in CController:

public function run($actionID)         {                   if(($action=$this->createAction($actionID))!==null)                   {                            if(($parent=$this->getModule())===null){                                     $parent=Yii::app();                            }                             if($parent->beforeControllerAction($this,$action))                            {                                     $this->runActionWithFilters($action,$this->filters());                                     $parent->afterControllerAction($this,$action);                            }                   }                   else                            $this->missingAction($actionID);         } 

 

You can view $ this-> createAction ($ actionID) and get return new CInlineAction ($ this, $ actionID );

Let's take a look at this CInlineAction later. Let's first look at $ this-> runActionWithFilters ($ action, $ this-> filters ());

public function runActionWithFilters($action,$filters)         {                   if(empty($filters)){                            $this->runAction($action);                   }                   else                   {                            $priorAction=$this->_action;                            $this->_action=$action;                            CFilterChain::create($this,$action,$filters)->run();                            $this->_action=$priorAction;                   }         }

 

Obviously $ filters is empty, so execute the first expression $ this-> runAction ($ action );

 

public function runAction($action)         {                    $priorAction=$this->_action;                   $this->_action=$action;                   if($this->beforeAction($action))                   {                             if($action->runWithParams($this->getActionParams())===false){                                     $this->invalidActionParams($action);                            }                             else{                                     $this->afterAction($action);                             }                    }                   $this->_action=$priorAction;         }

 

 

The focus of this Code is $ action-> runWithParams ($ this-> getActionParams;

$ Action here is the result returned by $ this-> createAction ($ actionID), and the result is

Return new CInlineAction ($ this, $ actionID );

 

CInlineAction. php

It is time to view CInlineAction;

 

 public function runWithParams($params)         {                   $methodName='action'.$this->getId();                   $controller=$this->getController();                   $method=new ReflectionMethod($controller, $methodName);                   if($method->getNumberOfParameters()>0)                            return $this->runWithParamsInternal($controller, $method, $params);                   else                            return $controller->$methodName();         }

 

Wow, I still use reflection, but I like it!

However, Print $ method and find:

Object (ReflectionMethod) #6 (2 ){

 

["Name"] =>

 

String (11) "actionIndex"

 

["Class"] =>

 

String (14) "SiteController"

 

}

No parameter, so the code here is equivalent to executing SiteController-> actionIndex ();

You can see the definition of actionIndex in class SiteController extends CController.

 public function actionIndex()         {                   echo 'Hello World';         }

 

So we can see the Hello World on the screen, and the whole program is running out. Some people may ask, why is the output of a sentence so complicated? Isn't it a fart with your pants off? (Allow me to be vulgar );

If it is such a simple requirement, of course it is impossible to do so. This example illustrates the basic process of yii and makes a transition for the following complex applications.

Yii is an excellent oop framework. This example only introduces its inheritance, interfaces, vc features in mvc, and I will give it in subsequent analysis. The ultimate goal is to use the yii framework to simplify our development process.

Well, today's analysis is coming. If there is anything wrong, please leave a message. If you think it is helpful, please give us a suggestion!

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.