<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                說到配置項,讀者朋友們第一反應是不是Yii的配置文件?這是一段配置文件的代碼: ~~~ return [ 'id' => 'app-frontend', 'basePath' => dirname(__DIR__), 'bootstrap' => ['log'], 'controllerNamespace' => 'frontend\controllers', 'components' => [ 'db' => [ 'class' => 'yii\db\Connection', 'dsn' => 'mysql:host=localhost;dbname=yii2advanced', 'username' => 'root', 'password' => '', 'charset' => 'utf8', ], ... ... 'cache' => [ 'class' => 'yii\caching\MemCache', 'servers' => [ [ 'host' => 'cache1.digpage.com', 'port' => 11211, 'weight' => 60, ], [ 'host' => 'cache2.digpage.com', 'port' => 11211, 'weight' => 40, ], ], ], ], 'params' => [...], ]; ~~~ Yii中許多地方都要用到配置項,Yii應用自身和其他幾乎一切類對象的創建、初始化、配置都要用到配置項。 配置項是針對對象而言的,也就是說,配置項一定是用于配置某一個對象,用于初始化或配置對象的屬性。 關于屬性的有關內容,請查看?[_屬性(Property)_](http://www.digpage.com/property.html#property)?。 ## 配置項的格式[](http://www.digpage.com/configuration.html#id2 "Permalink to this headline") 一個配置文件包含了3個部分: * 基本信息配置。主要指如?id?basePath?等這些應用的基本信息,主要是一些簡單的字符串。 * components配置。配置文件的主體,也是我們接下來要講的配置項。 * params配置。主要是提供一些全局參數。 我們一般講的配置項是指component配置項及里面的子項。 簡單來講,一個配置項采用下面的格式: ~~~ [ 'class' => 'path\to\ClassName', 'propertyName' => 'propertyValue', 'on eventName' => $eventHandler, 'as behaviorName' => $behaviorConfig, ] ~~~ 作為配置項: * 配置項以數組進行組織。 * class?數組元素表示將要創建的對象的完整類名。 * propertyName?數組元素表示指定為?propertyName?屬性的初始值為?$propertyValue?。 * on?eventName?數組元素表示將?$eventHandler?綁定到對象的?eventName?事件中。 * as?behaviorName?數組元素表示用?$behaviorConfig?創建一個行為,并注入到對象中。 這里的$behaviroConfig?也是一個配置項; * 配置項可以嵌套。 其中,?class?元素僅在特定的情況下可以沒有。就是使用配置數組的時候,其類型已經是確定的。 這往往是用于重新配置一個已經存在的對象, 或者是在創建對象時,使用了?new?或Yii::createObject()?指定了類型。 除此以外的大多數情況?class?都是配置數組的必備元素: ~~~ // 使用 new 時指定了類型,配置數組中就不應再有 class 元素 $connection = new \yii\db\Connection([ 'dsn' => $dsn, 'username' => $username, 'password' => $password, ]); // 使用 Yii::createObject()時,如果第一個參數指定了類型,也不應在配置數 // 組中設定 class $db = Yii::createObject('yii\db\Connection', [ 'dsn' => 'mysql:host=127.0.0.1;dbname=demo', 'username' => 'root', 'password' => '', 'charset' => 'utf8', ]); // 對現有的對象重新配置時,也不應在配置數組中設定 class Yii::configure($db, [ 'dsn' => 'mysql:host=127.0.0.1;dbname=demo', 'username' => 'root', 'password' => '', 'charset' => 'utf8', ]); ~~~ 上面的例子中,在沒看到配置數組的內容前,已經可以確定對象的類型了。 這種其他情況下,配置數組中如果再有一個 class 元素來設定類型的話,就不合理了。 這種情況下,配置數組不能有 class 元素。 但除此以外的其他情況,均要求配置數組提供 class 元素,以表示要創建的對象的類型。 ## 配置項產生作用的原理[](http://www.digpage.com/configuration.html#id3 "Permalink to this headline") 從?[_環境和配置文件_](http://www.digpage.com/environment.html#environment)?部分的內容,我們了解到了一個Yii應用,特別是高級模版應用,是具有許多個配置文件的, 這些配置文件在入口腳本?index.php?中被引入, 然后按照一定的規則合并成一個配置數組?$config?并用于創建Application對象。 具體可以看看?[_入口文件index.php_](http://www.digpage.com/app_struct.html#entry-script)?部分的內容。在入口腳本中,調用了: ~~~ $application = new yii\web\Application($config); ~~~ 在?yii\web\Application?中,會調用父類的構造函數?yii\base\Application::__construct($config)?, 來創建Web Application。在這個構造函數中: ~~~ public function __construct($config = []) { Yii::$app = $this; $this->setInstance($this); $this->state = self::STATE_BEGIN; // 預處理配置項 $this->preInit($config); $this->registerErrorHandler($config); // 使用 yii\base\Component::__construct() 完成構建 Component::__construct($config); } ~~~ 可以看到,其實分成兩步,一是對?$config?進行預處理, 二是使用yii\base\Component::__construct($config)?進行構建。 ### 配置項預處理[](http://www.digpage.com/configuration.html#id4 "Permalink to this headline") 預處理配置項的?yii\base\Application::preInit()?方法其實在?[_別名(Alias)_](http://www.digpage.com/aliases.html#aliases)?部分講過, 當時主要是從預定義別名的角度來講的。現在我們再來完整地看看這個方法和有關的屬性: ~~~ // basePath屬性,由Application的父類yii\base\Module定義,并提供getter和setter private $_basePath; // runtimePath屬性和vendorPath屬性,Application都為其定義了getter和setter。 private $_runtimePath; private $_vendorPath; // 還有一個timeZone屬性,Application為其提供了getter和setter,但不提供存 // 儲變量。 // 而是分別調用 PHP 的 date_default_timezone_get() 和 // date_default_timezone_set() public function preInit(&$config) { // 配置數組中必須指定應用id,這里僅判斷,不賦值。 if (!isset($config['id'])) { throw new InvalidConfigException( 'The "id" configuration for the Application is required.'); } // 設置basePath屬性,這個屬性在Application的父類 yii\base\Module 中定義。 // 在完成設置后,刪除配置數組中的 basePath 配置項 if (isset($config['basePath'])) { $this->setBasePath($config['basePath']); unset($config['basePath']); } else { throw new InvalidConfigException( 'The "basePath" configuration for the Application is required.'); } // 設置vendorPath屬性,并在設置后,刪除$config中的相應配置項 if (isset($config['vendorPath'])) { $this->setVendorPath($config['vendorPath']); unset($config['vendorPath']); } else { // set "@vendor" $this->getVendorPath(); } // 設置runtimePath屬性,并在設置后,刪除$config中的相應配置項 if (isset($config['runtimePath'])) { $this->setRuntimePath($config['runtimePath']); unset($config['runtimePath']); } else { // set "@runtime" $this->getRuntimePath(); } // 設置timeZone屬性,并在設置后,刪除$config中的相應配置項 if (isset($config['timeZone'])) { $this->setTimeZone($config['timeZone']); unset($config['timeZone']); } elseif (!ini_get('date.timezone')) { $this->setTimeZone('UTC'); } // 將coreComponents() 所定義的核心組件配置,與開發者通過配置文件定義 // 的組件配置進行合并。 // 合并中,開發者配置優先,核心組件配置起補充作用。 foreach ($this->coreComponents() as $id => $component) { // 配置文件中沒有的,使用核心組件的配置 if (!isset($config['components'][$id])) { $config['components'][$id] = $component; // 配置文件中有的,但并未指組件的class的,使用核心組件的class } elseif (is_array($config['components'][$id]) && !isset($config['components'][$id]['class'])) { $config['components'][$id]['class'] = $component['class']; } } } ~~~ 從上面的代碼可以看出,這個?preInit()?對配置數組?$config?作了以下處理: * id?屬性是必不可少的。 * 從?$config?中拿掉了?basePath?runtimePath?vendorPath?和?timeZone?4個屬性的配置項。 當然,也設置了相應的屬性。 * 對?$config['components']?配置項進行兩方面的補充。 一是配置文件中沒有的,而核心組件有的,把核心組件的配置信息補充進去。 二是配置文件中雖然也有,但沒有指定組件的class的,使用核心組件配置信息指定的class。 基于此,我們不難得出如下結論: * 有的配置項如?id?是不可少的,有的配置項如?basePath?等不用我們設置也是有默認值的。 * 對于核心組件,我們不配置也可以使用。 * 核心組件的ID是提前安排好的,沒有充足的理由一般不要改變他,否則以后接手的人會罵你的。 * 核心組件可以不指明?class?,默認會使用預先安排的類型。 對于核心組件,不同的應用有不同的安排,這個我們可以看看,大致了解下,具體在于各應用的coreComponents()?中定義: ~~~ // yii\base\Application 的核心組件 public function coreComponents() { return [ 'log' => ['class' => 'yii\log\Dispatcher'], // 日志組件 'view' => ['class' => 'yii\web\View'], // 視圖組件 'formatter' => ['class' => 'yii\i18n\Formatter'], // 格式組件 'i18n' => ['class' => 'yii\i18n\I18N'], // 國際化組件 'mailer' => ['class' => 'yii\swiftmailer\Mailer'], // 郵件組件 'urlManager' => ['class' => 'yii\web\UrlManager'], // url管理組件 'assetManager' => ['class' => 'yii\web\AssetManager'], // 前端資源管理組件 'security' => ['class' => 'yii\base\Security'], // 安全組件 ]; } // yii\web\Application 的核心組件,在基類的基礎上加入Web應用必需的組件 public function coreComponents() { return array_merge(parent::coreComponents(), [ 'request' => ['class' => 'yii\web\Request'], // HTTP請求組件 'response' => ['class' => 'yii\web\Response'], // HTTP響應組件 'session' => ['class' => 'yii\web\Session'], // session組件 'user' => ['class' => 'yii\web\User'], // 用戶管理組件 'errorHandler' => ['class' => 'yii\web\ErrorHandler'], // 錯誤處理組件 ]); } // yii\console\Application 的核心組件, public function coreComponents() { return array_merge(parent::coreComponents(), [ 'request' => ['class' => 'yii\console\Request'], // 命令行請求組件 'response' => ['class' => 'yii\console\Response'], // 命令行響應組件 'errorHandler' => ['class' => 'yii\console\ErrorHandler'], // 錯誤處理組件 ]); } ~~~ 這些我們大致有個印象就夠了,不用刻意去記住,用著用著你就自然記住了。 ### 使用配置數組構造應用[](http://www.digpage.com/configuration.html#id5 "Permalink to this headline") 在使用?preInit()?完成配置數組的預處理之后, Application構造函數又直接調用yii\base\Component::__construct()?來構造Application對象。 結果這個?yii\base\Component::__construct()?也是個推委扯皮的家伙,他根本就沒自己定義。 而是直接繼承了父類的?yii\base\Object::__construct()?。因此,Application構造函數的最后一步, 實際上調用的是?yii\base\Object::__construct($config)?。 這個函數的原理,我們在?[_Object的配置方法_](http://www.digpage.com/property.html#object-config)?部分已經作出解釋,這里就不再重復。 只是這里有兩類特殊的配置項需要注意,就是以?on?*?打頭的事件和以?as?*?打頭的行為。 對于事件行為,可以閱讀?[_事件(Event)_](http://www.digpage.com/event.html#event)?和?[_行為(Behavior)_](http://www.digpage.com/behavior.html#behavior)?部分的內容。 Yii對于這兩類配置項的處理,是在?yii\base\Component::__set()?中完成的,從Component開始, 才支持事件和行為。具體處理的代碼如下: ~~~ public function __set($name, $value) { $setter = 'set' . $name; if (method_exists($this, $setter)) { $this->$setter($value); return; // 'on ' 打頭的配置項在這里處理 } elseif (strncmp($name, 'on ', 3) === 0) { // 對于 'on event' 配置項,將配置值作為事件 handler 綁定到 evnet 上去 $this->on(trim(substr($name, 3)), $value); return; // 'as ' 打頭的配置項在這里處理 } elseif (strncmp($name, 'as ', 3) === 0) { // 對于 'as behavior' 配置項,將配置值作為創建Behavior的配置,創 // 建后綁定為 behavior $name = trim(substr($name, 3)); $this->attachBehavior($name, $value instanceof Behavior ? $value : Yii::createObject($value)); return; } else { $this->ensureBehaviors(); foreach ($this->_behaviors as $behavior) { if ($behavior->canSetProperty($name)) { $behavior->$name = $value; return; } } } if (method_exists($this, 'get' . $name)) { throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name); } else { throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name); } } ~~~ 從上面的代碼中可以看到,對于?on?event?形式配置項,Yii視配置值為一個事件handler,綁定到event?上。 而對于?as?behavior?形式的配置項,視配置值為一個Behavior,注入到當前實例中,并冠以?behavior?的名稱。 如果覺得《深入理解Yii2.0》對您有所幫助,也請[幫助《深入理解Yii2.0》](http://www.digpage.com/donate.html#donate)。 謝謝!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看