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()`。对 `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 是动作类的基类。
这些更改对你代码最明显的影响是,控制器动作应该返回你想要呈现的内容,而不是回显它
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
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 对象来表示数据库查询,该对象可以在 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 时。
有关更多详细信息,请参阅 Query Builder 部分。
Yii 2.0 对 Active Record 做了很多更改。最明显的两个更改涉及查询构建和关系查询处理。
Yii 2.0 中的 yii\db\ActiveQuery 替换了 1.1 中的 CDbCriteria
类。该类继承自 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 Behavior,您需要直接从 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,这使用起来要简单得多。高级项目模板提供了这样的示例。
有关更多详细信息,请参阅 Authentication、Authorization 和 Advanced Project Template 部分。
Yii 2 中的 URL 管理与 1.1 中的 URL 管理类似。主要增强功能是 URL 管理现在支持可选参数。例如,如果您声明了如下规则,那么它将同时匹配 post/popular
和 post/1/popular
。在 1.1 中,您需要使用两个规则才能实现相同的目标。
[
'pattern' => 'post/<page:\d+>/<tag>',
'route' => 'post/index',
'defaults' => ['page' => 1],
]
有关更多详细信息,请参阅 Url manager docs 部分。
路由命名约定中的一个重要变化是,控制器和操作的驼峰命名法现在转换为小写字母,每个单词之间用连字符分隔,例如 CamelCaseController
的控制器 ID 将为 camel-case
。有关更多详细信息,请参阅有关 控制器 ID 和 操作 ID 的部分。
如果您有要与 Yii 2.0 一起使用的旧版 Yii 1.1 代码,请参阅 同时使用 Yii 1.1 和 2.0 部分。
发现错别字或您认为此页面需要改进?
在 github 上编辑它 !
讨论在控制器和操作中使用驼峰命名的段落不是很清楚。应该注意的是,任何包含大写字母的 Yii1 控制器或操作可能需要进行更改才能在 Yii2 下运行。此外,操作 ID 部分的链接不存在。
请 注册 或 登录 以发表评论。