Yii 1.1 和 2.0 版本之間存在許多差異,因為框架已針對 2.0 完全重寫。因此,從 1.1 版本升級並不像在次要版本之間升級那麼簡單。在本指南中,您將找到兩個版本之間的主要差異。
如果您之前未使用過 Yii 1.1,您可以安全地跳過本節,直接轉到「開始使用」。
請注意,Yii 2.0 引入的新功能比本摘要中涵蓋的更多。強烈建議您通讀整個權威指南,以了解所有這些功能。您之前必須自行開發的某些功能現在很可能已成為核心程式碼的一部分。
Yii 2.0 完全採用 Composer,事實上的 PHP 套件管理器。核心框架以及擴展的安裝都透過 Composer 處理。請參閱安裝 Yii 章節,以了解如何安裝 Yii 2.0。如果您想建立新的擴展,或將現有的 1.1 擴展轉換為與 2.0 相容的擴展,請參閱指南的 建立擴展 章節。
Yii 2.0 需要 PHP 5.4 或更高版本,這比 Yii 1.1 要求的 PHP 5.2 版本有了很大的改進。因此,在語言層面上存在許多您應該注意的差異。以下是關於 PHP 主要變更的摘要
[...elements...]
取代了 array(...elements...)
。<?=
用於視圖檔案中。從 PHP 5.4 開始使用是安全的。intl
PHP 擴展來支援國際化功能。Yii 2.0 中最明顯的變化是命名空間的使用。幾乎每個核心類別都有命名空間,例如 yii\web\Request
。「C」前綴不再用於類別名稱中。命名方案現在遵循目錄結構。例如,yii\web\Request
表示對應的類別檔案是 Yii 框架資料夾下的 web/Request.php
。
(您可以使用任何核心類別,而無需顯式包含該類別檔案,這要歸功於 Yii 類別載入器。)
Yii 2.0 將 1.1 中的 CComponent
類別拆分為兩個類別:yii\base\BaseObject 和 yii\base\Component。BaseObject 類別是一個輕量級的基底類別,允許透過 getter 和 setter 定義物件屬性。Component 類別從 BaseObject 擴展,並支援事件和行為。
如果您的類別不需要事件或行為功能,您應該考慮使用 BaseObject 作為基底類別。對於表示基本資料結構的類別通常是這種情況。
BaseObject 類別引入了一種統一的物件配置方式。BaseObject 的任何子類都應以以下方式宣告其建構函式(如果需要),以便可以正確配置
class MyClass extends \yii\base\BaseObject
{
public function __construct($param1, $param2, $config = [])
{
// ... initialization before configuration is applied
parent::__construct($config);
}
public function init()
{
parent::init();
// ... initialization after configuration is applied
}
}
在上述程式碼中,建構函式的最後一個參數必須採用配置陣列,其中包含用於在建構函式結尾初始化屬性的名稱-值對。您可以覆寫 init() 方法來執行應在應用配置後完成的初始化工作。
透過遵循此慣例,您將能夠使用配置陣列建立和配置新物件
$object = Yii::createObject([
'class' => 'MyClass',
'property1' => 'abc',
'property2' => 'cde',
], [$param1, $param2]);
有關配置的更多詳細資訊,請參閱配置章節。
在 Yii 1 中,事件是透過定義 on
-方法(例如 onBeforeSave
)建立的。在 Yii 2 中,您現在可以使用任何事件名稱。您可以透過呼叫 trigger() 方法來觸發事件
$event = new \yii\base\Event;
$component->trigger($eventName, $event);
若要將處理常式附加到事件,請使用 on() 方法
$component->on($eventName, $handler);
// To detach the handler, use:
// $component->off($eventName, $handler);
事件功能有許多增強功能。有關更多詳細資訊,請參閱事件章節。
Yii 2.0 將路徑別名的用法擴展到檔案/目錄路徑和 URL。Yii 2.0 現在還要求別名名稱以 @
字元開頭,以將別名與普通檔案/目錄路徑或 URL 區分開來。例如,別名 @yii
指的是 Yii 安裝目錄。路徑別名在 Yii 核心程式碼的大多數地方都受到支援。例如,yii\caching\FileCache::$cachePath 可以同時採用路徑別名和普通目錄路徑。
路徑別名也與類別命名空間密切相關。建議為每個根命名空間定義路徑別名,從而允許您使用 Yii 類別自動載入器,而無需任何其他配置。例如,由於 @yii
指的是 Yii 安裝目錄,因此可以自動載入 yii\web\Request
等類別。如果您使用第三方程式庫(例如 Zend Framework),您可以定義路徑別名 @Zend
,該別名指的是該框架的安裝目錄。完成此操作後,Yii 也將能夠自動載入該 Zend Framework 程式庫中的任何類別。
有關路徑別名的更多資訊,請參閱別名章節。
Yii 2 中視圖最顯著的變化是視圖中的特殊變數 $this
不再指向目前的控制器或小部件。相反,$this
現在指向 *視圖* 物件,這是 2.0 中引入的新概念。*視圖* 物件的類型為 yii\web\View,它表示 MVC 模式的視圖部分。如果您想在視圖中存取控制器或小部件,可以使用 $this->context
。
若要在另一個視圖中呈現部分視圖,您可以使用 $this->render()
,而不是 $this->renderPartial()
。現在也必須顯式 echo 對 render
的呼叫,因為 render()
方法會傳回呈現結果,而不是直接顯示它。例如
echo $this->render('_item', ['item' => $item]);
除了使用 PHP 作為主要模板語言外,Yii 2.0 還配備了對兩種流行的模板引擎的官方支援:Smarty 和 Twig。不再支援 Prado 模板引擎。若要使用這些模板引擎,您需要透過設定 View::$renderers 屬性來配置 view
應用程式組件。請參閱模板引擎章節以取得更多詳細資訊。
Yii 2.0 使用 yii\base\Model 作為基底模型,類似於 1.1 中的 CModel
。類別 CFormModel
已完全刪除。相反,在 Yii 2 中,您應該擴展 yii\base\Model 來建立表單模型類別。
Yii 2.0 引入了一個名為 scenarios() 的新方法,用於宣告支援的場景,並指示在哪些場景下屬性需要驗證,可以視為安全與否等等。例如
public function scenarios()
{
return [
'backend' => ['email', 'role'],
'frontend' => ['email', '!role'],
];
}
在上述程式碼中,宣告了兩個場景:backend
和 frontend
。對於 backend
場景,email
和 role
屬性都是安全的,並且可以大量指派。對於 frontend
場景,email
可以大量指派,而 role
不能。email
和 role
都應使用規則進行驗證。
rules() 方法仍然用於宣告驗證規則。請注意,由於引入了 scenarios(),因此不再有 unsafe
驗證器。
在大多數情況下,如果 rules() 方法完全指定了將存在的場景,並且不需要宣告 unsafe
屬性,則您不需要覆寫 scenarios()。
若要了解有關模型的更多詳細資訊,請參閱模型章節。
Yii 2.0 使用 yii\web\Controller 作為基底控制器類別,這與 Yii 1.1 中的 CController
類似。yii\base\Action 是動作類別的基底類別。
這些變更對您的程式碼最明顯的影響是,控制器動作應該傳回您要呈現的內容,而不是 echo 它
public function actionView($id)
{
$model = \app\models\Post::findOne($id);
if ($model) {
return $this->render('view', ['model' => $model]);
} else {
throw new \yii\web\NotFoundHttpException;
}
}
有關控制器的更多詳細資訊,請參閱控制器章節。
Yii 2.0 使用 yii\base\Widget 作為基底小部件類別,類似於 Yii 1.1 中的 CWidget
。
為了在 IDE 中更好地支援框架,Yii 2.0 引入了一種使用小部件的新語法。已引入靜態方法 begin()、end() 和 widget(),用法如下
use yii\widgets\Menu;
use yii\widgets\ActiveForm;
// Note that you have to "echo" the result to display it
echo Menu::widget(['items' => $items]);
// Passing an array to initialize the object properties
$form = ActiveForm::begin([
'options' => ['class' => 'form-horizontal'],
'fieldConfig' => ['inputOptions' => ['class' => 'input-xlarge']],
]);
... form input fields here ...
ActiveForm::end();
有關更多詳細資訊,請參閱小部件章節。
主題在 2.0 中的運作方式完全不同。它們現在基於路徑對應機制,該機制將來源視圖檔案路徑對應到主題視圖檔案路徑。例如,如果主題的路徑對應是 ['/web/views' => '/web/themes/basic']
,則視圖檔案 /web/views/site/index.php
的主題版本將是 /web/themes/basic/site/index.php
。因此,主題現在可以應用於任何視圖檔案,甚至是控制器或小部件上下文之外呈現的視圖。
此外,不再有 CThemeManager
組件。相反,theme
是 view
應用程式組件的可配置屬性。
有關更多詳細資訊,請參閱主題化章節。
控制台應用程式現在像 Web 應用程式一樣組織為控制器。控制台控制器應從 yii\console\Controller 擴展,類似於 1.1 中的 CConsoleCommand
。
若要執行控制台命令,請使用 yii <route>
,其中 <route>
代表控制器路由(例如 sitemap/index
)。額外的匿名引數作為參數傳遞給對應的控制器動作方法,而具名引數則根據 yii\console\Controller::options() 中的宣告進行解析。
Yii 2.0 支援從註解區塊自動生成命令說明資訊。
有關更多詳細資訊,請參閱控制台命令章節。
Yii 2.0 移除了內建的日期格式器和數字格式器部分,轉而使用 PECL intl PHP 模組。
訊息翻譯現在透過 i18n
應用程式組件執行。此組件管理一組訊息來源,這允許您根據訊息類別使用不同的訊息來源。
有關更多詳細資訊,請參閱國際化章節。
動作過濾器現在透過行為實作。若要定義新的自訂過濾器,請從 yii\base\ActionFilter 擴展。若要使用過濾器,請將過濾器類別作為行為附加到控制器。例如,若要使用 yii\filters\AccessControl 過濾器,您可以在控制器中使用以下程式碼
public function behaviors()
{
return [
'access' => [
'class' => 'yii\filters\AccessControl',
'rules' => [
['allow' => true, 'actions' => ['admin'], 'roles' => ['@']],
],
],
];
}
有關更多詳細資訊,請參閱過濾章節。
Yii 2.0 引入了一個名為 *資源包* 的新概念,它取代了 Yii 1.1 中找到的腳本套件概念。
資源包是目錄中資源檔案(例如 JavaScript 檔案、CSS 檔案、影像檔案等)的集合。每個資源包都表示為擴展 yii\web\AssetBundle 的類別。透過透過 yii\web\AssetBundle::register() 註冊資源包,您可以透過 Web 存取該資源包中的資源。與 Yii 1 不同,註冊資源包的頁面將自動包含對該資源包中指定的 JavaScript 和 CSS 檔案的引用。
有關更多詳細資訊,請參閱管理資源章節。
Yii 2.0 引入了許多常用的靜態助手類別,包括。
有關更多詳細資訊,請參閱助手概覽章節。
Yii 2.0 為使用 yii\widgets\ActiveForm 建構表單引入了 *欄位* 概念。欄位是一個容器,由標籤、輸入、錯誤訊息和/或提示文字組成。欄位表示為 ActiveField 物件。使用欄位,您可以比以前更簡潔地建構表單
<?php $form = yii\widgets\ActiveForm::begin(); ?>
<?= $form->field($model, 'username') ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<div class="form-group">
<?= Html::submitButton('Login') ?>
</div>
<?php yii\widgets\ActiveForm::end(); ?>
有關更多詳細資訊,請參閱建立表單章節。
在 1.1 中,查詢建構分散在多個類別中,包括 CDbCommand
、CDbCriteria
和 CDbCommandBuilder
。Yii 2.0 以 Query 物件的形式表示 DB 查詢,該物件可以在幕後借助 QueryBuilder 轉換為 SQL 語句。例如
$query = new \yii\db\Query();
$query->select('id, name')
->from('user')
->limit(10);
$command = $query->createCommand();
$sql = $command->sql;
$rows = $command->queryAll();
最棒的是,在使用 Active Record 時也可以使用這種查詢建構方法。
有關更多詳細資訊,請參閱查詢建構器章節。
Yii 2.0 為 Active Record 引入了許多變更。其中兩個最明顯的變更涉及查詢建構和關聯查詢處理。
1.1 中的 CDbCriteria
類別在 Yii 2 中被 yii\db\ActiveQuery 取代。該類別從 yii\db\Query 擴展,因此繼承了所有查詢建構方法。您可以呼叫 yii\db\ActiveRecord::find() 開始建構查詢
// To retrieve all *active* customers and order them by their ID:
$customers = Customer::find()
->where(['status' => $active])
->orderBy('id')
->all();
若要宣告關聯,只需定義一個傳回 ActiveQuery 物件的 getter 方法即可。getter 定義的屬性名稱表示關聯名稱。例如,以下程式碼宣告了 orders
關聯(在 1.1 中,您必須在中心位置 relations()
中宣告關聯)
class Customer extends \yii\db\ActiveRecord
{
public function getOrders()
{
return $this->hasMany('Order', ['customer_id' => 'id']);
}
}
現在您可以使用 $customer->orders
從相關表格存取客戶的訂單。您也可以使用以下程式碼使用自訂查詢條件執行即時關聯查詢
$orders = $customer->getOrders()->andWhere('status=1')->all();
在急切載入關聯時,Yii 2.0 的做法與 1.1 不同。特別是,在 1.1 中,將建立 JOIN 查詢以選擇主要記錄和關聯記錄。在 Yii 2.0 中,執行兩個 SQL 語句而不使用 JOIN:第一個語句傳回主要記錄,第二個語句透過使用主要記錄的主鍵進行過濾來傳回關聯記錄。
您可以鏈式 asArray() 方法,而不是傳回 ActiveRecord 物件,以便在建構查詢時傳回大量記錄。如果記錄數量很大,這將導致查詢結果以陣列形式傳回,這可以顯著減少所需的 CPU 時間和記憶體。例如
$customers = Customer::find()->asArray()->all();
另一個變化是您不能再透過公用屬性定義屬性預設值。如果您需要這些值,您應該在記錄類別的 init 方法中設定它們。
public function init()
{
parent::init();
$this->status = self::STATUS_NEW;
}
在 1.1 中覆寫 ActiveRecord 類別的建構函式存在一些問題。這些問題在 2.0 版本中已不再存在。請注意,當向建構函式新增參數時,您可能必須覆寫 yii\db\ActiveRecord::instantiate()。
Active Record 還有許多其他變更和增強功能。請參閱Active Record章節以取得更多詳細資訊。
在 2.0 中,我們已刪除基底行為類別 CActiveRecordBehavior
。如果您想建立 Active Record 行為,您必須直接從 yii\base\Behavior
擴展。如果行為類別需要回應擁有者的某些事件,您必須覆寫 events()
方法,如下所示
namespace app\components;
use yii\db\ActiveRecord;
use yii\base\Behavior;
class MyBehavior extends Behavior
{
// ...
public function events()
{
return [
ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate',
];
}
public function beforeValidate($event)
{
// ...
}
}
1.1 中的 CWebUser
類別現在被 yii\web\User 取代,並且不再有 CUserIdentity
類別。相反,您應該實作 yii\web\IdentityInterface,它使用起來更直接。進階專案範本提供了這樣一個範例。
有關更多詳細資訊,請參閱身份驗證、授權和 Advanced Project Template 章節。
Yii 2 中的 URL 管理與 1.1 中的類似。一個主要的增強功能是 URL 管理現在支援可選參數。例如,如果您有如下宣告的規則,則它將同時匹配 post/popular
和 post/1/popular
。在 1.1 中,您必須使用兩個規則才能達到相同的目標。
[
'pattern' => 'post/<page:\d+>/<tag>',
'route' => 'post/index',
'defaults' => ['page' => 1],
]
有關更多詳細資訊,請參閱Url 管理器文件章節。
路由命名慣例的一個重要變更是,控制器和動作的駝峰式命名現在會轉換為小寫,其中每個單字以連字符分隔,例如 CamelCaseController
的控制器 ID 將為 camel-case
。有關更多詳細資訊,請參閱關於控制器 ID 和 動作 ID 的章節。
如果您有想要與 Yii 2.0 一起使用的舊版 Yii 1.1 程式碼,請參閱同時使用 Yii 1.1 和 2.0 章節。
發現錯字或您認為此頁面需要改進?
在 github 上編輯 !
討論控制器和動作中使用駝峰式命名法的段落不是很清楚。應該注意的是,任何包含大寫字母的 Yii1 控制器或動作都可能需要變更才能在 Yii2 下運行。此外,動作 ID 章節的連結不存在。
註冊 或 登入 以發表評論。