·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> php网站开发 >> yii源码分析1

yii源码分析1

作者:佚名      php网站开发编辑:admin      更新时间:2022-07-23
yii源码分析1

转载请注明:TheViperhttp://www.cnblogs.com/TheViper/

本文将对yii中的mvc,路由器,filter,组件机制等最主要的部分进行自己的一点浅析,力求说明自己做一个php mvc不是那么的遥不可及,其实是很简单的。

源码基于yii 1.13,为了方便说明,我对其进行了大量的裁剪,不过还是让他保有上面的那些最重要的功能。裁剪下来,其实没有几个文件了,而且每个文件代码最多100多行,避免因为代码太多而懒得看。

所谓的mvc都是让所有请求从一个地方进去,通过对请求,配置的解析,分发到对应的类方法中。

首先当然是入口文件,index.php.

1 <?php2 $app = "app";3 $yii = dirname ( __FILE__ ) . '/framework/yii.php';4 $config = dirname ( __FILE__ ) . '/app/PRotected/config/main.php';//载入配置5 require_once ($yii);6 Yii::createWebapplication ( $config )->run ();

引入yii.php

1 <?php2 define ( "VIEWS_DIR", "$app/protected/views/" );3 define ( "CONTROLLERS_DIR", "$app/protected/controllers/" );4 require(dirname(__FILE__).'/YiiBase.php');5 class Yii extends YiiBase6 {7 }

原来yii是个空的类啊,去看YiiBase.

  1 <?php  2 defined ( 'YII_PATH' ) or define ( 'YII_PATH', dirname ( __FILE__ ) );  3 class YiiBase {  4     public static $classMap = array ();  5     public static $enableIncludePath = true;  6     private static $_aliases = array (  7             'system' => YII_PATH   8     ); // alias => path  9     private static $_imports = array (); // alias => class name or directory 10     private static $_includePaths; // list of include paths 11     private static $_app; 12     private static $_logger; 13     public static function createWebApplication($config = null) { 14         return self::createApplication ( 'CWebApplication', $config ); 15     } 16     public static function createApplication($class, $config = null) { 17         return new $class ( $config ); 18     } 19     public static function app() { 20         return self::$_app; 21     } 22     //别名路径 23     public static function getPathOfAlias($alias) { 24         if (isset ( self::$_aliases [$alias] )) 25             return self::$_aliases [$alias]; 26         elseif (($pos = strpos ( $alias, '.' )) !== false) { 27             $rootAlias = substr ( $alias, 0, $pos ); 28             if (isset ( self::$_aliases [$rootAlias] )) 29                 return self::$_aliases [$alias] = rtrim ( self::$_aliases [$rootAlias] . DIRECTORY_SEPARATOR . str_replace ( '.', DIRECTORY_SEPARATOR, substr ( $alias, $pos + 1 ) ), '*' . DIRECTORY_SEPARATOR ); 30         } 31         return false; 32     } 33     public static function setPathOfAlias($alias, $path) { 34         if (empty ( $path )) 35             unset ( self::$_aliases [$alias] ); 36         else 37             self::$_aliases [$alias] = rtrim ( $path, '\\/' ); 38     } 39     public static function setApplication($app) { 40         if (self::$_app === null || $app === null) 41             self::$_app = $app; 42     } 43     public static function import($alias, $forceInclude = false) { 44         if (isset ( self::$_imports [$alias] )) // previously imported 45             return self::$_imports [$alias]; 46          47         if (class_exists ( $alias, false ) || interface_exists ( $alias, false )) 48             return self::$_imports [$alias] = $alias; 49         if (($pos = strrpos ( $alias, '.' )) === false)         // a simple class name 50         { 51             // try to autoload the class with an autoloader if $forceInclude is true 52             if ($forceInclude && (Yii::autoload ( $alias, true ) || class_exists ( $alias, true ))) 53                 self::$_imports [$alias] = $alias; 54             return $alias; 55         } 56          57         $className = ( string ) substr ( $alias, $pos + 1 ); 58         $isClass = $className !== '*'; 59          60         if ($isClass && (class_exists ( $className, false ) || interface_exists ( $className, false ))) 61             return self::$_imports [$alias] = $className; 62          63         if (($path = self::getPathOfAlias ( $alias )) !== false) { 64             if ($isClass) { 65                 if ($forceInclude) { 66                     if (is_file ( $path . '.php' )) 67                         require ($path . '.php'); 68                     else 69                         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 ( 70                                 '{alias}' => $alias  71                         ) ) ); 72                     self::$_imports [$alias] = $className; 73                 } else 74                     self::$classMap [$className] = $path . '.php'; 75                 return $className; 76             } else             // a directory 77             { 78                 if (self::$_includePaths === null) { 79                     self::$_includePaths = array_unique ( explode ( PATH_SEPARATOR, get_include_path () ) ); 80                     if (($pos = array_search ( '.', self::$_includePaths, true )) !== false) 81                         unset ( self::$_includePaths [$pos] ); 82                 } 83                  84                 array_unshift ( self::$_includePaths, $path ); 85                  86                 if (self::$enableIncludePath && set_include_path ( '.' . PATH_SEPARATOR . implode ( PATH_SEPARATOR, self::$_includePaths ) ) === false) 87                     self::$enableIncludePath = false; 88                  89                 return self::$_imports [$alias] = $path; 90             } 91         } 92     } 93     //创建组件实例 94     public static function createComponent($config) { 95         if (is_string ( $config )) { 96             $type = $config; 97             $config = array (); 98         } elseif (isset ( $config ['class'] )) { 99             $type = $config ['class'];100             unset ( $config ['class'] );101         }102         if (! class_exists ( $type, false )) {103             $type = Yii::import ( $type, true );104         }105         if (($n = func_num_args ()) > 1) {106             $args = func_get_args ();107             if ($n === 2)108                 $object = new $type ( $args [1] );109             elseif ($n === 3)110                 $object = new $type ( $args [1], $args [2] );111             elseif ($n === 4)112                 $object = new $type ( $args [1], $args [2], $args [3] );113             else {114                 unset ( $args [0] );115                 $class = new ReflectionClass ( $type );116                 // Note: ReflectionClass::newInstanceArgs() is available for PHP 5.1.3+117                 // $object=$class->newInstanceArgs($args);118                 $object = call_user_func_array ( array (119                         $class,120                         'newInstance' 121                 ), $args );122             }123         } else124             $object = new $type ();125         foreach ( $config as $key => $value )126             $object->$key = $value;127         128         return $object;129     }130     //按需加载相应的php131     public static function autoload($className) {132         include self::$_coreClasses [$className];133     }134     private static $_coreClasses = array (135             'CApplication' => '/base/CApplication.php',136             'CModule' => '/base/CModule.php',137             'CWebApplication' => '/base/CWebApplication.php',138             'CUrlManager' => 'CUrlManager.php',139             'CComponent' => '/base/CComponent.php'140         ,    'CUrlRule' => 'CUrlRule.php',141             'CController' => 'CController.php',142             'CInlineAction' => '/actions/CInlineAction.php',143             'CAction' => '/actions/CAction.php',144             'CFilterChain' => '/filters/CFilterChain.php',145             'CFilter' => '/filters/CFilter.php',146             'CList' => '/collections/CList.php',147             'CHttpRequest' => 'CHttpRequest.php',148             'CDb' => 'CDb.php',149             'CInlineFilter' => 'filters/CInlineFilter.php' 150     );151 }152 153 spl_autoload_register ( array (154         'YiiBase',155         'autoload' 156 ) );

看似很多,其实就三个地方注意下就可以了

1.spl_autoload_register,用这个就可以实现传说中的按需加载相应的php了,坑爹啊。

2.createComponent($config)这个