欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PHP的Yii框架中YiiBase入口類的擴(kuò)展寫法示例

 更新時(shí)間:2016年03月17日 15:11:21   作者:吾愛  
這篇文章主要介紹了PHP的Yii框架中YiiBase入口類的擴(kuò)展寫法示例,同時(shí)詳細(xì)講解了import和autoload這兩個(gè)YiiBase中的重要方法,需要的朋友可以參考下

通過yiic.php自動(dòng)創(chuàng)建一個(gè)應(yīng)用后,入口文件初始代碼如下:

<?php
// change the following paths if necessary
$yii=dirname(__FILE__).'/../yii/framework/yii.php';
$config=dirname(__FILE__).'/protected/config/main.php';
// remove the following lines when in production mode
defined('YII_DEBUG') or define('YII_DEBUG',true);
// specify how many levels of call stack should be shown in each log message
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);
require_once($yii);
Yii::createWebApplication($config)->run();


其中第三行引入了一個(gè)yii.php的文件,這個(gè)可以在yii核心目錄里的framework/下找到,這個(gè)文件中定義了一個(gè)Yii類,并且繼承了YiiBase類。

代碼如下

require(dirname(__FILE__).'/YiiBase.php');
 
/**
 * Yii is a helper class serving common framework functionalities.
 *
 * It encapsulates {@link YiiBase} which provides the actual implementation.
 * By writing your own Yii class, you can customize some functionalities of YiiBase.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @package system
 * @since 1.0
 */
class Yii extends YiiBase
{
}

Yii::createWebApplication

這個(gè)方法實(shí)際上是在YiiBase父類中定義的,所以,Yii為我們預(yù)留了擴(kuò)展的可能。我們只需要在yii.php中添加我們想要擴(kuò)展的方法即可,在項(xiàng)目中直接使用 Yii::方法名() 調(diào)用。
為了將項(xiàng)目代碼和核心目錄完全分離,我個(gè)人覺得在項(xiàng)目目錄下使用另外一個(gè)yii.php來替代從核心目錄中包含yii.php更加好。

這里我用了更加極端的方法,我直接將yii這個(gè)類定義在了入口文件,并擴(kuò)展了一個(gè)全局工廠函數(shù) instance()方法,請(qǐng)看代碼:

<?php
// change the following paths if necessary
$yii=dirname(__FILE__).'/../yii/framework/YiiBase.php';
$config=dirname(__FILE__).'/protected/config/main.php';
// remove the following lines when in production mode
defined('YII_DEBUG') or define('YII_DEBUG',true);
// specify how many levels of call stack should be shown in each log message
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);
require_once($yii);
//擴(kuò)展基類
class Yii extends YiiBase{
  /**
   * 全局?jǐn)U展方法:工廠函數(shù)
   * @param type $alias 類庫別名
   */
  static function instance($alias){
    static $_class_ = array();
    $key = md5($alias);
    if(!isset($_class_[$key])){
      $_class_[$key] = self::createComponent($alias);
    }
    return $_class_[$key];
  }
}
Yii::createWebApplication($config)->run();


這個(gè)類是在最后一行Yii::createWebApplication()之前定義的,以保證Yii類能正常使用(不要把這個(gè)類放在文件末尾,會(huì)出錯(cuò)。)

在項(xiàng)目中任何地方,使用$obj = Yii::instance($alias);去實(shí)例化一個(gè)類,并且是單例模式。

YiiBase中的兩個(gè)比較重要的方法 (import,autoload)
然后看看YiiBase中的import方法就知道這些靜態(tài)變量是干嘛用的了:

 /* Yii::import()
* $alias: 要導(dǎo)入的類名或路徑
* $forceInclude false:只導(dǎo)入不include類文件,true則導(dǎo)入并include類文件
*/
 public static function import($alias, $forceInclude = false){  
 //Yii把所有的依賴放入到這個(gè)全局的$_imports數(shù)組中,名字不能重復(fù)
 //如果當(dāng)前依賴已經(jīng)被引入過了,那么直接返回
 if (isset(self::$_imports[$alias])) {    
    return self::$_imports[$alias];  
  }  
 //class_exists和interface_exists方法的第二個(gè)參數(shù)的值為false表示不autoload 
 if (class_exists($alias, false) || interface_exists($alias, false)) {    
   return self::$_imports[$alias] = $alias;  
 }  
 //如果傳進(jìn)來的是一個(gè)php5.3版本的命名空間格式的類(例如:\a\b\c.php)
 if (($pos = strrpos($alias, '\\')) !== false) {    
  //$namespace = a.b
  $namespace = str_replace('\\', '.', ltrim(substr($alias, 0, $pos), '\\')); 
  //判斷a.b這個(gè)路徑是否存在,或者a.b只是alias里面的一個(gè)鍵,調(diào)用該方法返回這個(gè)鍵對(duì)應(yīng)的值,比如'email' => realpath(__DIR__ . '/../vendor/cornernote/yii-email-module/email')
  if (($path = self::getPathOfAlias($namespace)) !== false) {   
    $classFile = $path . DIRECTORY_SEPARATOR . substr($alias, $pos + 1) . '.php';       
    if ($forceInclude) {        
     if (is_file($classFile)) {          
       require($classFile);        
      } else {          
      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('{alias}' => $alias)));        
     }        
     self::$_imports[$alias] = $alias;      
     } else {        
     self::$classMap[$alias] = $classFile;      
    }      
    return $alias;    
  } else {      
// try to autoload the class with an autoloader      
  if (class_exists($alias, true)) {        
    return self::$_imports[$alias] = $alias;      
  } else {        
    throw new CException(Yii::t('yii', 'Alias "{alias}" is invalid. Make sure it points to an existing directory or file.',          array('{alias}' => $namespace)));      
  }    
  }  
 }  
if (($pos = strrpos($alias, '.')) === false) // a simple class name 
 {    
  // try to autoload the class with an autoloader if $forceInclude is true    
  if ($forceInclude && (Yii::autoload($alias, true) || class_exists($alias, true))) {      
   self::$_imports[$alias] = $alias;    
   }    
  return $alias;  
 }  
 $className = (string)substr($alias, $pos + 1);  

 $isClass = $className !== '*';  
 if ($isClass && (class_exists($className, false) || interface_exists($className, false))) {    
  return self::$_imports[$alias] = $className;  
 }  
 if (($path = self::getPathOfAlias($alias)) !== false) {    
   if ($isClass) {      
      if ($forceInclude) {        
         if (is_file($path . '.php')) {          
             require($path . '.php');        
         } else {          
             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('{alias}' => $alias)));        
             }        
        self::$_imports[$alias] = $className;      
     } else {        
        self::$classMap[$className] = $path . '.php';      
     }      
      return $className;    
    } 
    // $alias是'system.web.*'這樣的已*結(jié)尾的路徑,將路徑加到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);      
    if (self::$enableIncludePath && set_include_path('.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, self::$_includePaths)) === false) {        
     self::$enableIncludePath = false;      
     }      
     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)));  
    }
 }

是的,上面這個(gè)方法最后就把要加載的東西都放到$_imports,$_includePaths中去了。這就是Yii的import方法,好的,接下來我們看看autoload方法:

public static function autoload($className, $classMapOnly = false){  // use include so that the error PHP file may appear  
if (isset(self::$classMap[$className])) {       
  include(self::$classMap[$className]);  
} elseif (isset(self::$_coreClasses[$className])) {    
  include(YII_PATH . self::$_coreClasses[$className]);  
} elseif ($classMapOnly) {    
  return false;  
} else {    
 // include class file relying on include_path    
    if (strpos($className, '\\') === false) 
    // class without namespace    
    {      
      if (self::$enableIncludePath === false) {        
         foreach (self::$_includePaths as $path) {              
            $classFile = $path . DIRECTORY_SEPARATOR . $className . '.php';          
            if (is_file($classFile)) {       
               include($classFile);            
              if (YII_DEBUG && basename(realpath($classFile)) !== $className . '.php') {              
                throw new CException(Yii::t('yii', 'Class name "{class}" does not match class file "{file}".', array(                '{class}' => $className,                '{file}' => $classFile,              )));            
              }            
              break;          
           }        
       }      
   } else {        
      include($className . '.php');      
       }    
 } else // class name with namespace in PHP 5.3    
   {      
     $namespace = str_replace('\\', '.', ltrim($className, '\\'));    
     if (($path = self::getPathOfAlias($namespace)) !== false) {  
      include($path . '.php');      
     } else {        
      return false;      
     }    
   }    

   return class_exists($className, false) || interface_exists($className, false);    }    return true;}
config文件中的 import 項(xiàng)里的類或路徑在腳本啟動(dòng)中會(huì)被自動(dòng)導(dǎo)入。用戶應(yīng)用里個(gè)別類需要引入的類可以在類定義前加入 Yii::import() 語句。

相關(guān)文章

最新評(píng)論