<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                這部分內容是專門為已經有Yii1.1基礎的讀者朋友寫的。將Yii2.0與Yii1.1的不同點著重寫出來,對比學起來會快得多。 而對于從未接觸過Yii的讀者朋友,這部分內容掃一掃就可以了,作為對過往歷史的一個了解就夠了。 如果有的內容你一時沒看明白,也不要緊,本書的正文部分會講清楚的。 另外,沒有Yii1.1的經驗,并不妨礙對Yii2.0的學習。 Yii官方有專門的文檔歸納總結1.1版本和2.0版本的不同。以下內容,主要來自于官方的文檔,我做了下精簡, 選擇比較重要的變化,并加入了一些個人的經驗。 ## PHP新特性[](http://www.digpage.com/improvement.html#php "Permalink to this headline") 從對PHP新特性的使用上,兩者就存在很大不同。Yii2.0大量使用了PHP的新特性,這在Yii1.1中是沒有的。因此,Yii2.0對于PHP的版本要求更高,要求PHP5.4及以上。Yii2.0中使用到的PHP新特性,主要有: * 命名空間(Namespace) * 匿名函數 * 數組短語法形式:?[1,2,3]?取代?array(1,2,3)?。這在多維數組、嵌套數組中,代碼更清晰、簡短。 * 在視圖文件中使用PHP的??標簽,取代?echo?語句。 * 標準PHP庫(SPL) 類和接口,具體可以查看?[SPL Class and Interface](http://php.net/manual/en/book.spl.php) * 延遲靜態綁定, 具體可以查看?[Late Static Bindings](http://php.net/manual/en/language.oop5.late-static-bindings.php) * [PHP標準日期時間](http://php.net/manual/en/book.datetime.php) * [特性(Traits)](http://php.net/manual/en/language.oop5.traits.php) * 使用PHP?intl?擴展實現國際化支持, 具體可以查看?[PECL init](http://php.net/manual/en/book.intl.php)?。 了解Yii2.0使用了PHP的新特性,可以避免開發時由于環境不當,特別是開發生產環境切換時,產生莫名其妙的錯誤。 同時,也是讓讀者朋友借機學習PHP新知識的意思。 ## 命名空間(Namespace)[](http://www.digpage.com/improvement.html#namespace "Permalink to this headline") Yii2.0與Yii1.1之間最顯著的不同是對于PHP命名空間的使用。Yii1.1中沒有命名空間一說, 為避免Yii核心類與用戶自定義類的命名沖突,所有的Yii核心類的命名,均冠以?C?前綴,以示區別。 而Yii2.0中所有核心類都使用了命名空間,因此,?C?前綴也就人老珠黃,退出歷史舞臺了。 命名空間與實際路徑相關聯,比如?yii\base\Object?對應Yii目錄下的?base/Object.php?文件。 ## 基礎類[](http://www.digpage.com/improvement.html#id2 "Permalink to this headline") Yii1.1中使用了一個基礎類?CComponent?,提供了屬性支持等基本功能,因此幾乎所有的Yii核心類都派生自該類。 到了Yii2.0,將一家獨大的?CComponent?進行了拆分。拆分成了?yii\base\Object?和yii\base\Component?。 拆分的考慮主要是?CComponent?尾大不掉,有影響性能之嫌。 于是,Yii2.0中,把?yii\base\Object?定位于只需要屬性支持,無需事件、行為。 而?yii\base\Component?則在前者的基礎上,加入對于事件和行為的支持。 這樣,開發者可以根據需要,選擇繼承自哪基礎類。 這一功能上的明確劃分,帶來了效率上的提升。在僅表示基礎數據結構,而非反映客觀事物的情況下,?yii\base\Object?比較適用。 值得一提的是,?yii\base\Object?與?yii\base\Component?兩者并不是同一層級的,前者是后者他爹。 ## 事件(Event)[](http://www.digpage.com/improvement.html#event "Permalink to this headline") 在Yii1.1中,通過一個?on?前綴的方法來創建事件,比如?CActiveRecord?中的?onBeforeSave()?。 在Yii2.0中,可以任意定義事件的名稱,并自己觸發它: ~~~ $event = new \yii\base\Event; // 使用 trigger() 觸發事件 $component->trigger($eventName, $event); // 使用 on() 前事件handler與對象綁定 $component->on($eventName, $handler); // 使用 off() 解除綁定 $component->off($eventName, $handler); ~~~ ## 別名(Alias)[](http://www.digpage.com/improvement.html#alias "Permalink to this headline") Yii2.0中改變了Yii1.1中別名的使用形式,并擴大了別名的范疇。 Yii1.1中,別名以?.?的形式使用: ~~~ RootAlias.path.to.target ~~~ 而在Yii2.0中,別名以?@?前綴的方式使用: ~~~ @yii/jui ~~~ 另外,Yii2.0中,不僅有路徑別名,還有URL別名: ~~~ // 路徑別名 Yii::setAlias('@foo', '/path/to/foo'); // URL別名 Yii::setAlias('@bar', 'http://www.example.com'); ~~~ 別名與命名空間是緊密相關的,Yii建議為所有根命名空間都定義一個別名,比如上面提到的yii\base\Object?, 事實上是定義了?@yii?的別名,表示Yii在系統中的安裝路徑。 這樣一來,Yii就能根據命名空間找到實際的類文件所在路徑,并自動加載。這一點上,Yii2.0與Yii1.1并沒有本質區別。 而如果沒有為根命名空間定義別名,則需要進行額外的配置。將命名空間與實際路徑的映射關系,告知Yii。 關于別名的更詳細內容請看?[_別名(Alias)_](http://www.digpage.com/aliases.html#aliases)?。 ## 視圖(View)[](http://www.digpage.com/improvement.html#view "Permalink to this headline") Yii1.1中,MVC(model-view-controller)中的視圖一直是依賴于Controller的,并非是真正意義上獨立的View。 Yii2.0引入了?yii\web\View?類,使得View完全獨立。這也是一個相當重要變化。 首先,Yii2.0中,View作為Application的一個組件,可以在全局中代碼中進行訪問。 因此,視圖渲染代碼不必再局限于Controller中或Widget中。 其次,Yii1.1中視圖文件中的?$this?指的是當前控制器,而在 Yii2.0中,指的是視圖本身。 要在視圖中訪問控制器,可以使用?$this->context?。這個?$this->context?是指誰調用了yii\base\View::renderFile()?來渲染這個視圖。 一般是某個控制器,也可以是其他實現了yii\base\ViewContextInterface?接口的對象。 同時,Yii1.1中的?CClientScript?也被淘汰了,相關的前端資源及其依賴關系的管理,交由Assert Bundle?yii\web\AssertBundle?來專職處理。 一個Assert Bundle代表一系列的前端資源,這些前端資源以目錄形式進行管理,這樣顯得更有序。 更為重要的是,Yii1.1中需要你格外注意資源在HTML中的順序,比如CSS文件的順序(后面的會覆蓋前面的), JavaScript文件的順序(前后順序出錯會導致有的庫未加載)等。 而在Yii2.0中,使用一個Assert Bundle可以定義依賴于另外的一個或多個Assert Bundle的關系, 這樣在向HTML頁面注冊這些CSS或者JavaScript時,Yii2.0會自動把所依賴的文件先注冊上。 在視圖模版引擎方面,Yii2.0仍然使用PHP作為主要的模版語言。 同時官方提供了兩個擴展以支持當前兩大主流PHP模版引擎:Smarty和Twig,而對于Pardo引擎官方不再提供支持了。 當然,開發者可以通過設置?yii\web\View::$renderers?來使用其他模版。 另外,Yii1.1中,調用?$this->render('viewFile',?...)?是不需要使用?echo?命令的。 而Yii2.0中,記得?render()?只是返回視圖渲染結果,并不對直接顯示出來,需要自己調用?echo ~~~ echo $this->render('_item', ['item' => $item]); ~~~ 如果有一天你發現怎么Yii輸出了個空白頁給你,就要注意是不是忘記使用?echo?了。 還別說,這個錯誤很常見,特別是在對Ajax請求作出響應時,會更難發現這一錯誤。請你們編程時留意。 在視圖的主題(Theme)化方面,Yii2.0的運作機理采用了完全不同的方式。 在Yii2.0中,使用路徑映射的方式,將一個源視圖文件路徑,映射成一個主題化后的視圖文件路徑。 因此,['/web/views'?=>?'/web/themes/basic']?定義了一個主題映射關系, 源視圖文件/web/views/site/index.php?主題化后將是?/web/themes/basic/site/index.php?。 因此, Yii1.1中的CThemeManager?也被淘汰了。 ## 模型(Model)[](http://www.digpage.com/improvement.html#model "Permalink to this headline") MVC中的M指的就是模型,Yii1.1中使用?CModel?來表示,而Yii2.0使用?yii\base\Model?來表示。 Yii1.1中,?CFormModel?用來表示用戶的表單輸入,以區別于數據庫中的表。 這在Yii2.0中也被淘汰,Yii2.0傾向于使用繼承自?yii\base\Model?來表示提交的表單數據。 另外,Yii2.0為Model引入了?yii\base\Model::load()?和?yii\base\Model::loadMutiple()?兩個新的方法, 用于簡化將用戶輸入的表單數據賦值給Model: ~~~ // Yii2.0使用load()等同于下面Yii1.1的用法 $model = new Post; if ($model->load($_POST)) { ... ... } // Yii1.1中常用的套路 if (isset($_POST['Post'])) { $model->attributes = $_POST['Post']; } ~~~ 另外一個重要變化就是Yii2.0中改變了Model應用于不同場景的邏輯。通過引入yii\base\Model::scenarios()?來集中管理場景,使得一個Model所有適用的場景都比較清晰,一目了然。而Yii1.1是沒有一個統一管理場景的方法的。 由此帶來的一個很容易出現的問題就是,當你聲明一個Model處于某一場景時,可能由于拼寫錯誤, 不小心將場景的名稱寫錯了,那么在Yii1.1中,這個錯誤的場景并沒有任何的提示。假設有以下情況: ~~~ class UserForm extends CFormModel { public $username; public $email; public $password; public $password_repeat; public $rememberMe=false; public function rules() { return array( // username 和 password 在所有場景中都要驗證 array('username, password', 'required'), // email 和 password_repeat 只在注冊場景中驗證 array('email, password_repeat', 'required', 'on'=>'Registration'), array('email', 'email', 'on'=>'Registration'), // rememberMe 僅在登陸場景中驗證 array('rememberMe', 'boolean', 'on'=>'Login'), ); } } ~~~ 這里針對UserForm的注冊和登陸兩個場景,設定了不同的驗證規則。接下來,你要在注冊場景中使用這個UserForm, 但你一不小心將?Registration?場景設定成了?SignUp?, 說實在,我不是學英文出身的,這兩個單詞的意思在我眼里是一樣一樣的。只是Yii不會智能到把這兩個場景等同起來。 那么Yii1.1將不會有任何的提示,并自動地使用第一個驗證規則,而用戶注冊時填寫的?email?和password_repeat?字段就被拋棄了。這在實際編程中,是經常出現的一個低級錯誤。 從這里可以看到,Yii1.1中對于場景,沒有一個集中統一的管理,也就是說一個Model可適用的場景, 是不確定的、任意的。通過?rules()?你很難一眼看出來一個Model可以適用于多少個場景,每個場景下都有哪些字段是有效的、需要驗證的。 而在Yii2.0中,由于引入了?yii\base\Model::scenarios()?新的方法, 將本Model所有適用的場景,及不同場景下的有效字段都進行了聲明, 這個邏輯就顯得清晰了。而且,如果使用了一個未聲明的場景,Yii2.0會有相應的提示, 這避免了上面這個低級錯誤的可能: ~~~ namespace app\models; use yii\db\ActiveRecord; class User extends ActiveRecord { public function scenarios() { return [ 'login' => ['username', 'password', 'rememberMe'], 'registration' => ['username', 'email', 'password', 'password_repeat'], ]; } } ~~~ 這樣看來,是不是很清晰?這個User僅有兩種場景,每種場景的有效字段也一目了然。 而至于具體場景下每個字段的驗證規則,仍然由?yii\base\Model::rules()?來確定。 這也意味著,?unsafe?驗證在Yii2.0中也沒有了立足之地,凡是?unsafe?的字段,就不在特定的場景中列出來。 或者為了更加明顯的表示某一字段在特定場景下是無效的,可以給這個字段加上?!?前綴。 在默認情況下,?yii\base\Model::scenarios()?所有適用的場景和對應的字段由yii\base\Model::rules()?的內容自動生成。也就是說,如果你的?rules()?很完備、很清晰,那么也是不需要重載這個?scenarios()?的。 這種情況下,Yii1.1和Yii2.0在這一點上的表現形式,是一樣的。但是,個人經驗看, 我更傾向于將?scenarios()?聲明清楚,而在?rules()?中,僅指定字段的驗證規則,而不涉及場景的內容。 這樣的邏輯更加清晰,便于其他團隊成員閱讀你的代碼,也便于后續的維護和開發。 ## 控制器(Controller)[](http://www.digpage.com/improvement.html#controller "Permalink to this headline") 除了上面講到的控制器中要使用?echo?來顯示渲染視圖的輸出這點區別外, Yii1.1與Yii2.0的控制器還表現出更為明顯的區別,那就是動作過濾器(Action Filter) 的不同。 在Yii2.0中,動作過濾器以行為(behavior)的方式出現, 一般繼承自?yii\base\ActionFilter?,并注入到一個控制器中,以發生作用。比如,Yii1.1中很常見的: ~~~ public function behaviors() { return [ 'access' => [ 'class' => 'yii\filters\AccessControl', 'rules' => [ ['allow' => true, 'actions' => ['admin'], 'roles' => ['@']], ], ], ]; } ~~~ 看著是不是有點像,但又確實不一樣? ## Active Record[](http://www.digpage.com/improvement.html#active-record "Permalink to this headline") 還記得么?在Yii1.1中,數據庫查詢被分散成?CDbCommand?,?CDbCriteria?和?CDbCommandBuilder?。 所謂天下大勢分久必合,到了Yii2.0,采用?yii\db\Query?來表示數據庫查詢: ~~~ $query = new \yii\db\Query(); $query->select('id, name') ->from('user') ->limit(10); $command = $query->createCommand(); $sql = $command->sql; $rows = $command->queryAll(); ~~~ 最最最爽的是,?yii\db\Query?可以在 Active Record中使用,而在Yii1.1中,要結合兩者,并不容易。 Active Record在Yii2.0中最大的變化一個是查詢的構建,另一個是關聯查詢的處理。 Yii1.1中的?CDbCriteria?在Yii2.0中被?yii\db\ActiveQuery?所取代, 這個把前輩拍死在沙灘上的家伙,繼承自?yii\db\Query?,所以可以進行類似上面代碼的查詢。 調用?yii\db\ActiveRecord::find()?就可以啟動查詢的構建了: ~~~ $customers = Customer::find() ->where(['status' => $active]) ->orderBy('id') ->all(); ~~~ 這在Yii1.1中,是不容易實現的。特別是比較復雜的查詢關系。 在關聯查詢方面,Yii1.1是在一個統一的地方?relations()?定義關聯關系。 而Yii2.0改變了這一做法,定義一個關聯關系: * 定義一個getter方法 * getter方法的方法名表示關聯關系的名稱,如?getOrders()?表示關系?orders * getter方法中定義關聯的依據,通常是外鍵關系 * getter返回一個?yii\db\ActiveQuery?對象 比如以下代碼就定義了?Customer?的?orders?關聯關系: ~~~ class Customer extends \yii\db\ActiveRecord { ... ... public function getOrders() { // 關聯的依據是 Order.customer_id = Customer.id return $this->hasMany('Order', ['customer_id' => 'id']); } } ~~~ 這樣的話,可以通過?Customer?訪問關聯的?Order ~~~ // 獲取所有與當前 $customer 關聯的 orders $orders = $customer->orders; // 獲取所有關聯 orders 中,status=1 的 orders $orders = $customer->getOrders()->andWhere('status=1')->all(); ~~~ 對于關聯查詢,有積極的方式也有消極的方式。區別在于采用積極方式時,關聯的查詢會一并執行, 而消極方式時,僅在顯示調用關聯記錄時材會執行關聯的查詢。 在積極方式的實現上,Yii2.0與Yii1.1也存在不同。Yii1.1使用一個JOIN查詢, 來實現同時查詢主記錄及其關聯的記錄。 而Yii2.0棄用JOIN查詢的方式,而使用兩個順序的SQL語句, 第一個語句查詢主記錄,第二個語句根據第一個語句的返回結果進行過濾。 同時,Yii2.0為Active Record引入了?asArray()?方法。在返回大量記錄時,可以以數組形式保存, 而不再以對象形式保存,這樣可以節約大量的空間,提高效率。 另外一個變化是,在Yii1.1中,字段的默認值可以通過為類的public 成員變量賦初始值來指定。 而在Yii2.0中,這樣的方式是行不通的,必須通過重載?init()?成員函數的方式實現了。 Yii2.0還淘汰掉了原來的?CActiveRecordBehavior?類。在Yii2.0中,將行為與類進行綁定采用了統一的方式進行, 具體請參考?[_行為(Behavior)_](http://www.digpage.com/behavior.html#behavior)?的有關內容。 Yii2.0中,ActiveRecord得到極大的加強,在相關的章節中我們已經進行專門的講解。 這里的內容主要是點一點Yii2.0之于Yii1.1的變化。大致了解下就可以了, 主要還是要看正文專門針對每個知識點的深入講解。 如果覺得《深入理解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>

                              哎呀哎呀视频在线观看