Yii

简介:





  Yii是一个基于组件的高性能PHP框架,用于开发大型Web应用。Yii采用严格的OOP编写,并有着完善的库引用以及全面的教程。从 MVC、DAO/ActiveRecord、Widgets、caching、等级式RBAC,Web服务,到主题化,I18N和L10N,Yii提供了今日Web 2.0应用开发所需要的几乎一切功能。从成功的网站应用相对于其它框架,Yii是最有效率的PHP框架之一。

     Yii是一个高性能的PHP5的web应用程序开发框架。通过一个简单的命令行工具 yiic 可以快速创建一个web应用程序的代码框架,开发者可以在生成的代码框架基础上添加业务逻辑,以快速完成应用程序的开发。

    Yii 是一个通用的 Web 编程框架,可以用于开发几乎所有的 Web 应用。由于它是轻量级的且具备了成熟的缓存解决方案,它特别适用于开发高流量的应用,例如门户,论坛,内容管理系统(CMS),电子商务系统等等。

   Yii和其它多数的PHP框架类似,Yii 首先也是一个MVC 框架。Yii 以其优异的性能,丰富的功能和清晰的文档优于其他PHP开发框架。Yii 从一开始就仔细设计以适合严谨的Web应用程序开发。它既不是一个其他项目的衍生品,也不是一个第三方工作的组合。 它是作者丰富的Web应用开发经验和对大多数流行的Web编程框架与应用的研究与思考的成果。


优点:


Yii容易学习和使用。只需要知道PHP和面向对象编程,便可以很快上手,而不必事先去学习一种新的架构或者模板语言。
用Yii的开发速度非常之快,除框架本身之外,需要为应用所写的编码极少。造就了Yii是最高效的开发框架之一。
Yii 具有高度的可重用性和可扩展性,是纯粹的面向对象。Yii中的一切都是独立的可被配置,可重用,可扩展的组件。更重要的是Yii有着越来越多的扩展库。主要由使用者贡献出的组件组成,这可能有助于大大减少开发时间。
Yii 有着丰富的功能,从MVC, DAO/ActiveRecord, 到主题化, 国际化和本地化, Yii 提供了几乎所有今天的Web 2.0应用程序开发所需的功能。
Yii参考手册是Yii完备的文档,有着学习和掌握它所需要的任何资料和信息。
Yii一开始就精心设计,以适应复杂的Web应用开发。它不是某个项目的副产品或者第三方集成。而是融合了作者丰富的Web应用开发经验和其它热门 Web 框架和应用的优秀思想的结晶。
最后,重要的一点:Yii是免费的,Yii遵循最新的BSD许可。它确保了它的第三方开发也循序和BSD相兼容的许可。这意味着无论从法律上还是财务上来说,都可以自由的使用Yii来开发任何一个开源的或者私有的应用。
它非常令人印象深刻的是,性能指标相比其他基于PHP的框架有明显效率,立即吸引了非常积极的关注并受到许多开发者的欢迎。


特性:


Yii几乎拥有了当今Web 2.0应用发展的全部特性。下面是这些特性的一个简短的清单。
模型-视图-控制器(MVC)设计模式:Yii在WEB编程中采用这一成熟的技术从而可以更好的将逻辑层和表现层分开。
数据库访问对象(DAO)和Active Record:Yii允许开发者模型数据库中的数据对象,从而减少他们在写很长和重复的SQL语句上的精力。
与jQuery整合:作为最流行的JavaScript框架之一,jQuery可以编写高效而灵活的JavaScript接口。
表单输入和验证:YII使得收集表单输入非常容易和安全。 Yii拥有一套确保数据的有效性的验证器,它也有辅助方法和部件,显示验证失败时的错误。
Web 2.0部件:由jQuery的支持,YII配备了一套Web 2.0的部件,如自动完成输入字段,TreeView等等。
身份验证和授权:Yii具有内置的身份验证支持。它也支持通过分层的基于角色的访问控制(RBAC)的授权。
主题:它能够瞬间改变一个Yii应用的视图。
Web服务:Yii支持自动生成复杂的WSDL服务规范和管理Web服务请求处理。
国际化(I18N)和本地化(L10N):Yii支持消息转换,日期和时间格式,数字格式和界面本地化。
分层缓存方案:Yii支持数据缓存,页面缓存,片段缓存和动态内容。缓存的存储介质,可以轻松地更改而不触及应用程序代码。
错误处理和日志记录:错误的处理很好的呈现出来,日志信息可以分类,过滤并分配到不同的位置。
安全:Yii配备了许多安全的措施,以帮助安全的Web应用程序,以防止网络攻击。这些措施包括跨站点脚本(XSS)预防,跨站点请求伪造(CSRF)预防,Cookie篡改预防等。
符合XHTML:Yii的组件和命令行工具生成的代码符合XHTML标准。
自动代码生成:Yii提供了可以自动生成的代码的工具,根据你的需要,例如生成一个程序骨架,CRUD应用等等。
完全面向对象:Yii框架坚持严格的面向对象编程范式。它没有定义任何全局函数或变量。而且,它定义的类层次结构允许最大的可重用性和定制。
友好的使用第三方代码:Yii精心设计让它第三方代码非常好的工作。例如,你可以在你的Yii应用程序中使用PEAR或Zend Framework的代码。
详细的文档:每一个单一的方法或属性都非常清楚的记录着。同时提供了一个全面的教程和一些新手教程。
扩展库:Yii提供了一个组成用户提供组件的一个扩展库,这使得上述功能列表是永无止境的。


设计参考:


Yii集成了许多其他著名Web编程框架、应用程序的思想。下面是Yii所吸收和设计上参考列表:
Prado:这是Yii思想的主要来源。Yii采用基于组件和事件驱动的编程范式,数据库抽象层,模块化的应用程序架构、国际化、本地化和许多其他的特点和规律。
Ruby on Rails:Yii的约定优于配置继承了它的精神。Yii的ORM层还引用了它的Active Record设计模式。
JQuery: 这是集成在Yii中的基本框架。
Symfony:Yii引用其过滤器的设计和插件体系结构。
Joomla:Yii引用了其模块化设计和信息翻译方案。


开发的必要条件:


要运行一个 Yii 驱动的Web应用,需要有一个支持 PHP 5.1.0 或以上版本的 Web服务器。对于打算使用Yii的开发者来说,首先要懂PHP程序开发语言,另外懂得面向对象编程(OOP)会非常有帮助,因为Yii 是一个纯 OOP 的PHP框架。


Yii 是什么

===========
 

Yii 是一个高性能,基于组件的 PHP 框架,用于快速开发现代 Web 应用程序。名字 Yii (读作 `易`)在中文里有 “极致简单与不断演变” 两重含义,也可看作 **Yes It Is**! 的缩写。
 

Yii 最适合做什么?

 


Yii 是一个通用的 Web 编程框架,即可以用于开发各种基于 PHP 的 Web 应用。因为基于组件的框架结构和设计精巧的缓存支持,Yii 特别适合开发大型应用,如门户网站、论坛、内容管理系统(CMS)、电子商务项目和 RESTful Web 服务等。
 

Yii 和其他框架相比呢?

 


- 和其他 PHP 框架类似,Yii 实现了 MVC(Model-View-Controller)设计模式并基于该模式组织代码。
- Yii 的代码简洁优雅,这是 Yii 的编程哲学。它永远不会为了要迎合某个设计模式而对代码进行过度的设计。
- Yii 是一个全栈框架,提供了大量久经考验,开箱即用的特性,例如:对关系型和 NoSQL 数据库都提供了查询生成器(QueryBuilders)和 ActiveRecord;RESTful API 的开发支持;多层缓存支持,等等。
- Yii 非常易于扩展。你可以自定义或替换几乎任何一处核心代码。你还会受益于它坚实可靠的扩展架构,使用、再开发或再发布扩展。
- 高性能始终是 Yii 的首要目标之一。
 
Yii 不是一场独角戏,它由一个[强大的开发者团队](http://www.yiiframework.com/about/)提供支持,也有一个庞大的专家社区,持续不断地对 Yii 的开发作出贡献。Yii 开发者团队始终对 Web 开发最新潮流和其他框架及项目中的最佳实践和特性保持密切关注,那些有意义的最佳实践及特性会被不定期的整合进核心框架中,并提供简单优雅的接口。
 

Yii 版本

 


Yii 当前有两个主要版本:1.1 和 2.0。 1.1 版是上代的老版本,现在处于维护状态。2.0 版是一个完全重写的版本,采用了最新的技术和协议,包括依赖包管理器(Composer)、PHP 代码规范(PSR)、命名空间、Traits(特质)等等。 2.0 版代表了最新一代框架,是未来几年中我们的主要开发版本。本指南主要基于 2.0 版编写。
 

系统要求和先决条件

 


Yii 2.0 需要 PHP 5.4.0 或以上版本支持。你可以通过运行任何 Yii 发行包中附带的系统要求检查器查看每个具体特性所需的 PHP 配置。
 
使用 Yii 需要对面向对象编程(OOP)有基本了解,因为 Yii 是一个纯面向对象的框架。Yii 2.0 还使用了 PHP 的最新特性,例如 [命名空间](http://www.php.net/manual/en/language.namespaces.php) 和 [Trait(特质)](http://www.php.net/manual/en/language.oop5.traits.php)。理解这些概念将有助于你更快地掌握 Yii 2.0。

从 Yii 1.1 升级




2.0 版框架是完全重写的,在 1.1 和 2.0 两个版本之间存在相当多差异。因此从 1.1 版升级并不像小版本间的跨越那么简单,通过本指南你将会了解两个版本间主要的不同之处。
 
如果你之前没有用过 Yii 1.1,可以跳过本章,直接从"[入门篇](start-installation.md)"开始读起。
 
请注意,Yii 2.0 引入了很多本章并没有涉及到的新功能。强烈建议你通读整部权威指南来了解所有新特性。这样有可能会发现一些以前你要自己开发的功能,而现在已经被包含在核心代码中了。
 

安装




Yii 2.0 完全拥抱 [Composer](https://getcomposer.org/),它是PHP中的一个依赖管理工具。核心框架以及扩展的安装都通过 Composer 来处理。想要了解更多如何安装 Yii 2.0 请参阅本指南的 [安装 Yii](start-installation.md) 章节。如果你想创建新扩展,或者把你已有的 Yii 1.1 的扩展改写成兼容 2.0 的版本,你可以参考 [创建扩展](extend-creating-extensions.md) 章节。
 

PHP 需求




Yii 2.0 需要 PHP 5.4 或更高版本,该版本相对于 Yii 1.1 所需求的 PHP 5.2 而言有巨大的改进。因此在语言层面上有很多的值得注意的不同之处。下面是 PHP 层的主要变化汇总:
 
- [命名空间](http://php.net/manual/zh/language.namespaces.php)
- [匿名函数](http://php.net/manual/zh/functions.anonymous.php)
- 数组短语法 `[...元素...]` 用于取代 `array(...元素...)`
- 视图文件中的短格式 echo 标签 `<?=`,自 PHP 5.4 起总会被识别并且合法,无论 short_open_tag 的设置是什么,可以安全使用。
- [SPL 类和接口](http://php.net/manual/zh/book.spl.php)
- [延迟静态绑定](http://php.net/manual/zh/language.oop5.late-static-bindings.php)
- [日期和时间](http://php.net/manual/zh/book.datetime.php)
- [Traits](http://php.net/manual/zh/language.oop5.traits.php)
- [intl](http://php.net/manual/zh/book.intl.php) Yii 2.0 使用 PHP 扩展 `intl` 来支持国际化的相关功能。
 
 

命名空间




Yii 2.0 里最明显的改动就数命名空间的使用了。几乎每一个核心类都引入了命名空间,比如 `yii\web\Request`。1.1 版用于类名前的字母 “C” 已经不再使用。当前的命名规范与目录结构相吻合。例如,`yii\web\Request` 就表明对应的类文件是 Yii 框架文件夹下的 `web/Request.php` 文件。
 
(有了 Yii 的类自动加载器,你可以直接使用全部核心类而不需要显式包含具体文件。)
 

组件(Component)与对象(Object)




Yii 2.0 把 1.1 里的 `CComponent` 类拆分成了两个类:[[yii\base\Object]] 和 [[yii\base\Component]]。[[yii\base\Object|Object]] 类是一个轻量级的基类,你可以通过 getters 和 setters 来定义 [object 的属性](concept-properties.md)。[[yii\base\Component|Component]] 类继承自 [[yii\base\Object|Object]],同时进一步支持 [事件](concept-events.md) 和 [行为](concept-behaviors.md)。
如果你不需要用到事件或行为,应该考虑使用 [[yii\base\Object|Object]] 类作为基类。这通常是表示基本数据结构的类。
 

对象的配置




[[yii\base\Object|Object]] 类引入了一种统一对象配置的方法。所有 [[yii\base\Object|Object]] 的子类都应该用以下方法声明它的构造方法(如果需要的话),以正确配置它自身:
 
class MyClass extends \yii\base\Object
{
    public function __construct($param1, $param2, $config = [])
    {
        // ... 配置生效前的初始化过程

        parent::__construct($config);
    }

    public function init()
    {
        parent::init();

        // ...配置生效后的初始化过程
    }
}
在上面的例子里,构造方法的最后一个参数必须输入一个配置数组,包含一系列用于在方法结尾初始化相关属性的键值对。你可以重写 [[yii\base\Object::init()|init()]] 方法来执行一些需要在配置生效后进行的初始化工作。
 
你可以通过遵循以下约定俗成的编码习惯,来使用配置数组创建并配置新的对象:
 
$object = Yii::createObject([
    'class' => 'MyClass',
    'property1' => 'abc',
    'property2' => 'cde',
], [$param1, $param2]);
 
更多有关配置的细节可以在[配置](concept-configurations.md)章节找到。
 

事件(Event)




在 Yii 1 中,通常通过定义 `on` 开头的方法(例如 `onBeforeSave`)来创建事件。而在 Yii 2 中,你可以使用任意的事件名了。同时通过调用 [[yii\base\Component::trigger()|trigger()]] 方法来触发相关事件:
 
$event = new \yii\base\Event;
$component->trigger($eventName, $event);
 
要给事件附加一个事件句柄(Event Handler 或者叫事件处理器),需要使用 [[yii\base\Component::on()|on()]] 方法:
 
$component->on($eventName, $handler);
// 要解除相关句柄,使用 off 方法:
// $component->off($eventName, $handler);
 
事件功能还有更多增强之处。要了解它们,请查看[事件](concept-events.md)章节。
 

路径别名(Path Alias)




Yii 2.0 将路径别名的应用扩大至文件/目录路径和 URL。Yii 2.0 中路径别名必须以 `@` 符号开头,以区别于普通文件目录路径或 URL。例如 `@yii` 就是指向 Yii 安装目录的别名。绝大多数 Yii 核心代码都支持别名。例如 [[yii\caching\FileCache::cachePath]] 就同时支持路径别名或普通的目录地址。
 
路径别名也和类的命名空间密切相关。建议给每一个根命名空间定义一个路径别名,从而无须额外配置,便可启动 Yii 的类自动加载机制。例如,因为有 `@yii` 指向 Yii 安装目录,那类似 `yii\web\Request` 的类就能被 Yii 自动加载。同理,若你用了一个第三方的类库,如 Zend Framework,你只需定义一个名为 `@Zend` 的路径别名指向该框架的安装目录。之后 Yii 就可以自动加载任意 Zend Framework 中的类了。
 
更多路径别名信息请参阅[路径别名](concept-aliases.md)章节。
 

视图(View)




Yii 2 中视图最明显的改动是视图内的特殊变量 `$this` 不再指向当前控制器或小部件,而是指向**视图**对象,它是 2.0 中引入的全新概念。**视图**对象为 [[yii\web\View]] 的实例,他代表了 MVC 模式中的视图部分。如果你想要在视图中访问一个控制器或小部件,可以使用 `$this->context`。
 
要在其他视图里渲染一个局部视图,使用 `$this->render()`,而不是 `$this->renderPartial()`。`render()` 现在只返回渲染结果,而不是直接显示它,所以现在你必须显式地把它 **echo** 出来。像这样:
 
echo $this->render('_item', ['item' => $item]);
 
除了使用 PHP 作为主要的模板语言,Yii 2.0 也装备了两种流行模板引擎的官方支持:Smarty 和 Twig。过去的 Prado 模板引擎不再被支持。要使用这些模板引擎,你需要配置 `view` 应用组件,给它设置 [[yii\base\View::$renderers|View::$renderers]] 属性。具体请参阅[模板引擎](tutorial-template-engines.md)章节。
 
 

模型(Model)




Yii 2.0 使用 [[yii\base\Model]] 作为模型基类,类似于 1.1 的 `CModel` 。`CFormModel` 被完全弃用了,现在要创建表单模型类,可以通过继承 [[yii\base\Model]] 类来实现。
 
Yii 2.0 引进了名为 [[yii\base\Model::scenarios()|scenarios()]] 的新方法来声明支持的场景,并指明在哪个场景下某属性必须经过验证,可否被视为安全值等等。如:
 
public function scenarios()
{
    return [
        'backend' => ['email', 'role'],
        'frontend' => ['email', '!role'],
    ];
}
 
上面的代码声明了两个场景:`backend` 和 `frontend` 。对于 `backend` 场景,`email` 和 `role` 属性值都是安全的,且能进行批量赋值。对于 `frontend` 场景,`email` 能批量赋值而 `role` 不能。 `email` 和 `role` 都必须通过规则验证。
 
[[yii\base\Model::rules()|rules()]] 方法仍用于声明验证规则。注意,由于引入了 [[yii\base\Model::scenarios()|scenarios()]],现在已经没有 `unsafe` 验证器了。
 
大多数情况下,如果 [[yii\base\Model::rules()|rules()]] 方法内已经完整地指定场景了,那就不必覆写 [[yii\base\Model::scenarios()|scenarios()]],也不必声明 `unsafe` 属性值。
 
要了解更多有关模型的细节,请参考[模型](structure-models.md)章节。
 

控制器(Controller)




Yii 2.0 使用 [[yii\web\Controller]] 作为控制器的基类,类似于 1.1 的 `CWebController`。使用 [[yii\base\Action]] 作为操作类的基类。
 
这些变化最明显的影响是,当你在写控制器操作的代码时,应该返回(return)要渲染的内容而不是输出(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;
    }
}
 
请查看 [控制器(Controller)](structure-controllers.md) 章节了解有关控制器的更多细节。
 

小部件(Widget)




Yii 2.0 使用 [[yii\base\Widget]] 作为小部件基类,类似于 1.1 的 `CWidget`。
 
为了让框架获得更好的 IDE 支持,Yii 2.0 引进了一个调用小部件的新语法。包含 [[yii\base\Widget::begin()|begin()]],[[yii\base\Widget::end()|end()]] 和 [[yii\base\Widget::widget()|widget()]] 三个静态方法,用法如下:
 
use yii\widgets\Menu;
use yii\widgets\ActiveForm;

// 注意必须 **"echo"** 结果以显示内容
echo Menu::widget(['items' => $items]);

// 传递一个用于初始化对象属性的数组
$form = ActiveForm::begin([
    'options' => ['class' => 'form-horizontal'],
    'fieldConfig' => ['inputOptions' => ['class' => 'input-xlarge']],
]);
... 表单输入栏都在这里 ...
ActiveForm::end();
更多细节请参阅[小部件](structure-widgets.md)章节。
 

主题(Theme)




2.0 主题的运作方式跟以往完全不同了。它们现在基于**路径映射机制**,该机制会把一个源视图文件的路径映射到一个主题视图文件路径。举例来说,如果路径映射为 `['/web/views' => '/web/themes/basic']`,那么 `/web/views/site/index.php` 视图经过主题修饰的版本就会是 `/web/themes/basic/site/index.php`。也因此让主题现在可以应用在任何视图文件之上,甚至是渲染控制器上下文环境之外的视图文件或小部件。
 
同样,`CThemeManager` 组件已经被移除了。取而代之的 `theme` 成为了 `view` 应用组件的一个可配置属性。
 
更多细节请参考[主题](output-theming.md)章节。
 

控制台应用(Console Application)




控制台应用现在如普通的 Web 应用程序一样,由控制器组成,控制台的控制器继承自 [[yii\console\Controller]],类似于 1.1 的 `CConsoleCommand`。
 
运行控制台命令使用 `yii <route>`,其中 `<route>` 代表控制器的路由(如 `sitemap/index`)。额外的匿名参数传递到对应的控制器操作方法,而有名的参数根据 [[yii\console\Controller::options()]] 的声明来解析。
 
Yii 2.0 支持基于代码注释自动生成相的关命令行帮助(help)信息。
 
更多细节请参阅[控制台命令](tutorial-console.md)章节。

国际化(I18N)




Yii 2.0 移除了原来内置的日期格式器和数字格式器,为了支持 [PECL intl PHP module](http://pecl.php.net/package/intl)(PHP 的国际化扩展)的使用。
 
消息翻译现在由 `i18n` 应用组件执行。该组件管理一系列消息源,允许使用基于消息类别的不同消息源。
 
更多细节请参阅[国际化(Internationalization)](tutorial-i18n.md)章节。
 

操作过滤器(Action Filters)




操作的过滤现在通过行为(behavior)来实现。要定义一个新的,自定义的过滤器,请继承 [[yii\base\ActionFilter]] 类。要使用一个过滤器,需要把过滤器类作为一个 `behavior` 绑定到控制器上。例如,要使用 [[yii\filters\AccessControl]] 过滤器,你需要在控制器内添加如下代码:
 
public function behaviors()
{
    return [
        'access' => [
            'class' => 'yii\filters\AccessControl',
            'rules' => [
                ['allow' => true, 'actions' => ['admin'], 'roles' => ['@']],
            ],
        ],
    ];
}
更多细节请参考[过滤器](structure-filters.md)章节。

前端资源(Assets)




Yii 2.0 引入了一个新的概念,称为**资源包**(Asset Bundle),以代替 1.1 的脚本包概念。
 
一个资源包是一个目录下的资源文件集合(如 JavaScript 文件、CSS 文件、图片文件等)。每一个资源包被表示为一个类,该类继承自 [[yii\web\AssetBundle]]。用 [[yii\web\AssetBundle::register()]] 方法注册一个资源包后,就使它的资源可被 Web 访问了,注册了资源包的页面会自动包含和引用资源包内指定的 JS 和 CSS 文件。
 
更多细节请参阅 [前端资源管理(Asset)](structure-assets.md) 章节。
 

助手类(Helpers)




Yii 2.0 很多常用的静态助手类,包括:
* [[yii\helpers\Html]]
* [[yii\helpers\ArrayHelper]]
* [[yii\helpers\StringHelper]]
* [[yii\helpers\FileHelper]]
* [[yii\helpers\Json]]
 
请参考[助手一览](helper-overview.md) 章节来了解更多。
 

表单




Yii 2.0 引进了**表单栏(field)**的概念,用来创建一个基于 [[yii\widgets\ActiveForm]]的表单。一个表单栏是一个由标签、输入框、错误消息(可能还有提示文字)组成的容器,被表示为 [[yii\widgets\ActiveField|ActiveField]] 对象。使用表单栏建立表单的过程比以前更整洁利落:
 
 <?php field($model, 'username') ?>
 <?php  field($model, 'password')->passwordInput() ?>
    
 
请参考[创建表单](input-forms.md)章节来了解更多细节。
 

查询生成器(Query Builder)

 


Yii 1.1 中,查询语句的生成分散在多个类中,包括 `CDbCommand`,`CDbCriteria` 以及 `CDbCommandBuilder`。Yii 2.0 以 [[yii\db\Query|Query]] 对象的形式表示一个数据库查询,这个对象使用 [[yii\db\QueryBuilder|QueryBuilder]] 在幕后生成 SQL 语句。例如:
 
$query = new \yii\db\Query();
$query->select('id, name')
      ->from('user')
      ->limit(10);

$command = $query->createCommand();
$sql = $command->sql;
$rows = $command->queryAll();
最重要的是,这些查询生成方法还可以和[活动记录](db-active-record.md)配合使用。
请参考[查询生成器(Query Builder)](db-query-builder.md)章节了解更多内容。

活动记录(Active Record)




Yii 2.0 的[活动记录](db-active-record.md)改动了很多。两个最显而易见的改动分别涉及查询语句的生成(query building)和关联查询的处理(relational query handling)。
1.1 中的 `CDbCriteria` 类在 Yii 2 中被 [[yii\db\ActiveQuery]] 所替代。这个类是继承自 [[yii\db\Query]],因此也继承了所有查询生成方法。开始拼装一个查询可以调用 [[yii\db\ActiveRecord::find()]] 方法进行:
 
// 检索所有 *活动的* 客户和订单,并以 ID 排序:
$customers = Customer::find()
    ->where(['status' => $active])
    ->orderBy('id')
    ->all();
要声明一个关联关系,只需简单地定义一个 getter 方法来返回一个 [[yii\db\ActiveQuery|ActiveQuery]] 对象。getter 方法定义的属性名(译者注:即 getOrders() 中的 orders)表示关联关系名。如,以下代码声明了一个名为 `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 中会使用两个没有 JOIN 的 SQL 语句:第一条语句取回主表记录,第二条通过主表记录经主键筛选后查询关联表记录。
 
当生成返回大量记录的查询时,可以链式书写 [[yii\db\ActiveQuery::asArray()|asArray()]] 方法,这样会以数组的形式返回查询结果,而不必返回
[[yii\db\ActiveRecord|ActiveRecord]] 对象,这能显著降低因大量记录读取所消耗的 CPU 时间和内存。如:
 
$customers = Customer::find()->asArray()->all();
另一个改变是你不能再通过公共数据定属性(Attribute)的默认值了。如果你需要这么做的话,可以在你的记录类的 `init` 方法中设置它们。
 
public function init()
{
    parent::init();
    $this->status = self::STATUS_NEW;
}
曾几何时,在 1.1 中重写一个活动记录类的构造方法(Constructor)会导致一些问题。它们不会在 2.0 中出现了。需要注意的是,如果你需要在构造方法中添加一些参数,恐怕必须重写 [[yii\db\ActiveRecord::instantiate()]] 方法。
活动记录方面还有很多其他的变化与改进,请参考[活动记录](db-active-record.md)章节以了解更多细节。
 

用户及身份验证接口(IdentityInterface)




1.1 中的 `CWebUser` 类现在被 [[yii\web\User]] 所取代,随之 `CUserIdentity` 类也不在了。与之相对的,为达到相同目的,你可以实现 [[yii\web\IdentityInterface]] 接口,它使用起来更直观。在高级应用模版里提供了一个这样的一个例子。
要了解更多细节请参考[认证(Authentication)](security-authentication.md),[授权(Authorization)](security-authorization.md)以及[高级应用模版](tutorial-advanced-app.md) 这三个章节。
 

URL 管理




Yii 2.0 的 URL 管理跟 1.1 中很像。一个主要的改进是现在的 URL 管理支持**可选参数**了。比如,如果你在 2.0 中定义了一个下面这样的规则,那么它可以同时匹配 `post/popular` 和 `post/1/popular` 两种 URL。而在 1.1 中为达成相同效果,必须要使用两条规则。
 
[
    'pattern' => 'post//',
    'route' => 'post/index',
    'defaults' => ['page' => 1],
]
请参考[URL 解析和生成](runtime-url-handling.md) 章节,以了解更多细节。.
 

同时使用 Yii 1.1 和 2.x




如果你有一些遗留的 Yii 1.1 代码,需要跟 Yii 2.0 一起使用,可以参考 [1.1 和 2.0 共用](extend-using-v1-v2.md)章节。


使用数据库

本章节将介绍如何如何创建一个从数据表 country 中获取国家数据并显示出来的页面。为了实现这个目标,你将会配置一个数据库连接,创建一个活动记录类,并且创建一个操作及一个视图。

贯穿整个章节,你将会学到:

  • 配置一个数据库连接
  • 定义一个活动记录类
  • 使用活动记录从数据库中查询数据
  • 以分页方式在视图中显示数据





请注意,为了掌握本章你应该具备最基本的数据库知识和使用经验。尤其是应该知道如何创建数据库,如何通过数据库终端执行 SQL 语句。

准备数据库



首先创建一个名为 yii2basic 的数据库,应用将从这个数据库中获取数据。你可以创建 SQLite,MySQL,PostregSQL,MSSQL 或 Oracle 数据库,Yii 内置多种数据库支持。简单起见后面的内容将以 MySQL 为例做演示。

然后在数据库中创建一个名为 country 的表并插入简单的数据。可以执行下面的语句:

CREATE TABLE `country` (
  `code` CHAR(2) NOT NULL PRIMARY KEY,
  `name` CHAR(52) NOT NULL,
  `population` INT(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `Country` VALUES ('AU','Australia',18886000);
INSERT INTO `Country` VALUES ('BR','Brazil',170115000);
INSERT INTO `Country` VALUES ('CA','Canada',1147000);
INSERT INTO `Country` VALUES ('CN','China',1277558000);
INSERT INTO `Country` VALUES ('DE','Germany',82164700);
INSERT INTO `Country` VALUES ('FR','France',59225700);
INSERT INTO `Country` VALUES ('GB','United Kingdom',59623400);
INSERT INTO `Country` VALUES ('IN','India',1013662000);
INSERT INTO `Country` VALUES ('RU','Russia',146934000);
INSERT INTO `Country` VALUES ('US','United States',278357000);

于是便有了一个名为 yii2basic 的数据库,在这个数据库中有一个包含三个字段的数据表 country,表中有十行数据。

配置数据库连接



开始之前,请确保你已经安装了 PHP PDO 扩展和你所使用的数据库的 PDO 驱动(例如 MySQL 的 pdo_mysql)。对于使用关系型数据库来讲,这是基本要求。

驱动和扩展安装可用后,打开 config/db.php 修改里面的配置参数对应你的数据库配置。该文件默认包含这些内容:

<?php

return [
    'class' => 'yiidbConnection',
    'dsn' => 'mysql:host=localhost;dbname=yii2basic',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
];

config/db/php 是一个典型的基于文件的配置工具。这个文件配置了数据库连接 [[yiidbConnection]] 的创建和初始化参数,应用的 SQL 查询正是基于这个数据库。

上面配置的数据库连接可以在应用中通过 Yii::$app->db 访问。

补充:config/db.php 将被包含在应用配置文件 config/web.php 中,后者指定了整个应用如何初始化。请参考配置章节了解更多信息。

创建活动记录






创建一个继承自活动记录类的类 Country,把它放在 models/Country.php,去表示和获取 country 表的数据。

<?php

namespace appmodels;

use yiidbActiveRecord;

class Country extends ActiveRecord
{
}

这个 Country 类继承自 [[yiidbActiveRecord]]。你不用在里面写任何代码。只需要像现在这样,Yii 就能根据类名去猜测对应的数据表名。

补充:如果类名和数据表名不能直接对应,可以重写 [[yiidbActiveRecord::tableName()|tableName()]] 方法去显式指定相关表名。




使用 Country 类可以很容易地操作 country 表数据,就像这段代码:

use appmodelsCountry;

// 获取 country 表的所有行并以 name 排序
$countries = Country::find()->orderBy('name')->all();

// 获取主键为 “US” 的行
$country = Country::findOne('US');

// 输出 “United States”
echo $country->name;

// 修改 name 为 “U.S.A.” 并在数据库中保存更改
$country->name = 'U.S.A.';
$country->save();

补充:活动记录是面向对象、功能强大的访问和操作数据库数据的方式。你可以在活动记录章节了解更多信息。除此之外你还可以使用另一种更原生的称做数据访问对象的方法操作数据库数据。

创建操作






为了向最终用户显示国家数据,你需要创建一个操作。相比之前小节掌握的在 site 控制器中创建操作,在这里为所有和国家有关的数据新建一个控制器更加合理。新控制器名为CountryController,并在其中创建一个 index 操作,如下:

<?php

namespace appcontrollers;

use yiiwebController;
use yiidataPagination;
use appmodelsCountry;

class CountryController extends Controller
{
    public function actionIndex()
    {
        $query = Country::find();

        $pagination = new Pagination([
            'defaultPageSize' => 5,
            'totalCount' => $query->count(),
        ]);

        $countries = $query->orderBy('name')
            ->offset($pagination->offset)
            ->limit($pagination->limit)
            ->all();

        return $this->render('index', [
            'countries' => $countries,
            'pagination' => $pagination,
        ]);
    }
}

把上面的代码保存在 controllers/CountryController.php

index 操作调用了活动记录 Country::find() 方法,去生成查询语句并从 country 表中取回所有数据。为了限定每个请求所返回的国家数量,查询在 [[yiidataPagination]] 对象的帮助下进行分页。 Pagination 对象的使命主要有两点:

  • 为 SQL 查询语句设置 offset 和 limit 从句,确保每个请求只需返回一页数据(本例中每页是 5 行)。
  • 在视图中显示一个由页码列表组成的分页器,这点将在后面的段落中解释。




在代码末尾,index 操作渲染一个名为 index 的视图,并传递国家数据和分页信息进去。

创建视图



在 views 目录下先创建一个名为 country 的子目录。这个目录存储所有由 country 控制器渲染的视图。在 views/country 目录下创建一个名为 index.php 的视图文件,内容如下:

<?php
use yiihelpersHtml;
use yiiwidgetsLinkPager;
?>
<h1>Countries</h1>
<ul>
<?php foreach ($countries as $country): ?>
    <li>
        <?= Html::encode("{$country->name} ({$country->code})") ?>:
        <?= $country->population ?>
    </li>
<?php endforeach; ?>
</ul>

<?= LinkPager::widget(['pagination' => $pagination]) ?>

这个视图包含两部分用以显示国家数据。第一部分遍历国家数据并以无序 HTML 列表渲染出来。第二部分使用 [[yiiwidgetsLinkPager]] 去渲染从操作中传来的分页信息。小部件LinkPager 显示一个分页按钮的列表。点击任何一个按钮都会跳转到对应的分页。

尝试下



浏览器访问下面的 URL 看看能否工作:

http://hostname/index.php?r=country/index

国家列表

首先你会看到显示着五个国家的列表页面。在国家下面,你还会看到一个包含四个按钮的分页器。如果你点击按钮 “2”,将会跳转到显示另外五个国家的页面,也就是第二页记录。如果观察仔细点你还会看到浏览器的 URL 变成了:

http://hostname/index.php?r=country/index&page=2

在这个场景里,[[yiidataPagination|Pagination]] 提供了为数据结果集分页的所有功能:

  • 首先 [[yiidataPagination|Pagination]] 把 SELECT 的子查询 LIMIT 5 OFFSET 0 数据表示成第一页。因此开头的五条数据会被取出并显示。
  • 然后小部件 [[yiiwidgetsLinkPager|LinkPager]] 使用 [[yiidataPagination::createUrl()|Pagination::createUrl()]] 方法生成的 URL 去渲染翻页按钮。URL 中包含必要的参数 page 才能查询不同的页面编号。
  • 如果你点击按钮 “2”,将会发起一个路由为 country/index 的新请求。[[yiidataPagination|Pagination]] 接收到 URL 中的 page 参数把当前的页码设为 2。新的数据库请求将会以 LIMIT 5 OFFSET 5 查询并显示。

总结









本章节中你学到了如何使用数据库。你还学到了如何取出并使用 [[yiidataPagination]] 和 [[yiiwidgetsLinkPager]] 显示数据。

下一章中你会学到如何使用 Yii 中强大的代码生成器 Gii,去帮助你实现一些常用的功能需求,例如增查改删(CRUD)数据表中的数据。事实上你之前所写的代码全部都可以由 Gii 自动生成。



使用 Gii 生成代码

本章节将介绍如何使用 Gii 去自动生成 Web 站点常用功能的代码。使用 Gii 生成代码非常简单,只要按照 Gii 页面上的介绍输入正确的信息即可。

贯穿本章节,你将会学到:

  • 在你的应用中开启 Gii
  • 使用 Gii 去生成活动记录类
  • 使用 Gii 去生成数据表操作的增查改删(CRUD)代码
  • 自定义 Gii 生成的代码

开始 Gii






Gii 是 Yii 中的一个模块。可以通过配置应用的 [[yiiaseApplication::modules|modules]] 属性开启它。通常来讲在 config/web.php 文件中会有以下配置代码:

$config = [ ... ];

if (YII_ENV_DEV) {
    $config['bootstrap'][] = 'gii';
    $config['modules']['gii'] = 'yiigiiModule';
}

这段配置的意思是如果当前是开发环境,应用会包含 gii 模块,模块类是 [[yiigiiModule]]。

如果你检查应用的入口脚本 web/index.php,将看到这行代码将 YII_ENV_DEV 设为 true:

defined('YII_ENV') or define('YII_ENV', 'dev');

代码设置应用处于开发模式下,按照上面的配置会打开 Gii 模块。你可以直接通过 URL 访问 Gii:

http://hostname/index.php?r=gii

Gii

生成活动记录类



选择 “Model Generator” (点击 Gii 首页的链接)去生成活动记录类。并像这样填写表单:

  • Table Name: country
  • Model Class: Country

模型生成器


然后点击 “Preview” 按钮。你会看到 models/Country.php 被列在将要生成的文件列表中。可以点击文件名预览内容。

如果你已经创建过同样的文件,使用 Gii 可以覆写它,点击文件名旁边的 diff 能查看现有文件与将要生成的文件的内容区别。

模型生成器预览

想要覆写已存在文件,选中 “overwrite” 下的复选框然后点击 “Generator”。如果是新文件,只点击 “Generator” 就好。

接下来你会看到一个包含已生成文件的说明页面。如果生成过程中覆写过文件,还会有一条信息说明代码是重新生成覆盖的。

生成 CRUD 代码



CRUD 代表增,查,改,删操作,这是绝大多数 Web 站点常用的数据处理方式。选择 Gii 中的 “CRUD Generator” (点击 Gii 首页的链接)去创建 CRUD 功能。之前的 “country” 例子需要像这样填写表单:

  • Model Class: appmodelsCountry
  • Search Model Class: appmodelsCountrySearch
  • Controller Class: appcontrollersCountryController

CRUD 生成器



然后点击 “Preview” 按钮。你会看到下述将要生成的文件列表。

[[NEED THE IMAGE HERE / 等待官方补充图片]]

如果你之前创建过 controllers/CountryController.php 和 views/country/index.php 文件(在指南的使用数据库小节),选中 “overwrite” 下的复选框覆写它们(之前的文件没能全部支持 CRUD)。

尝试下



用浏览器访问下面的 URL 查看生成代码的运行:

http://hostname/index.php?r=country/index

可以看到一个栅格显示着从数据表中获取的国家数据。支持在列头对数据进行排序,输入筛选条件进行筛选。

可以浏览详情,编辑,或删除栅格中的每个国家。还可以点击栅格上方的 “Create Country” 按钮通过表单创建新国家。

国家的数据栅格

编辑一个国家

下面列出由 Gii 生成的文件,以便你研习功能和实现,或修改它们。

  • 控制器:controllers/CountryController.php
  • 模型:models/Country.php 和 models/CountrySearch.php
  • 视图:views/country/*.php

补充:Gii 被设计成高度可定制和可扩展的代码生成工具。使用它可以大幅提高应用开发速度。请参考 Gii 小节了解更多内容。

总结







本章学习了如何使用 Gii 去生成为数据表中数据实现完整 CRUD 功能的代码。


使用数据库

本章节将介绍如何如何创建一个从数据表 country 中获取国家数据并显示出来的页面。为了实现这个目标,你将会配置一个数据库连接,创建一个活动记录类,并且创建一个操作及一个视图。

贯穿整个章节,你将会学到:

  • 配置一个数据库连接
  • 定义一个活动记录类
  • 使用活动记录从数据库中查询数据
  • 以分页方式在视图中显示数据





请注意,为了掌握本章你应该具备最基本的数据库知识和使用经验。尤其是应该知道如何创建数据库,如何通过数据库终端执行 SQL 语句。

准备数据库



首先创建一个名为 yii2basic 的数据库,应用将从这个数据库中获取数据。你可以创建 SQLite,MySQL,PostregSQL,MSSQL 或 Oracle 数据库,Yii 内置多种数据库支持。简单起见后面的内容将以 MySQL 为例做演示。

然后在数据库中创建一个名为 country 的表并插入简单的数据。可以执行下面的语句:

CREATE TABLE `country` (
  `code` CHAR(2) NOT NULL PRIMARY KEY,
  `name` CHAR(52) NOT NULL,
  `population` INT(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `Country` VALUES ('AU','Australia',18886000);
INSERT INTO `Country` VALUES ('BR','Brazil',170115000);
INSERT INTO `Country` VALUES ('CA','Canada',1147000);
INSERT INTO `Country` VALUES ('CN','China',1277558000);
INSERT INTO `Country` VALUES ('DE','Germany',82164700);
INSERT INTO `Country` VALUES ('FR','France',59225700);
INSERT INTO `Country` VALUES ('GB','United Kingdom',59623400);
INSERT INTO `Country` VALUES ('IN','India',1013662000);
INSERT INTO `Country` VALUES ('RU','Russia',146934000);
INSERT INTO `Country` VALUES ('US','United States',278357000);

于是便有了一个名为 yii2basic 的数据库,在这个数据库中有一个包含三个字段的数据表 country,表中有十行数据。

配置数据库连接



开始之前,请确保你已经安装了 PHP PDO 扩展和你所使用的数据库的 PDO 驱动(例如 MySQL 的 pdo_mysql)。对于使用关系型数据库来讲,这是基本要求。

驱动和扩展安装可用后,打开 config/db.php 修改里面的配置参数对应你的数据库配置。该文件默认包含这些内容:

<?php

return [
    'class' => 'yiidbConnection',
    'dsn' => 'mysql:host=localhost;dbname=yii2basic',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
];

config/db/php 是一个典型的基于文件的配置工具。这个文件配置了数据库连接 [[yiidbConnection]] 的创建和初始化参数,应用的 SQL 查询正是基于这个数据库。

上面配置的数据库连接可以在应用中通过 Yii::$app->db 访问。

补充:config/db.php 将被包含在应用配置文件 config/web.php 中,后者指定了整个应用如何初始化。请参考配置章节了解更多信息。

创建活动记录






创建一个继承自活动记录类的类 Country,把它放在 models/Country.php,去表示和获取 country 表的数据。

<?php

namespace appmodels;

use yiidbActiveRecord;

class Country extends ActiveRecord
{
}

这个 Country 类继承自 [[yiidbActiveRecord]]。你不用在里面写任何代码。只需要像现在这样,Yii 就能根据类名去猜测对应的数据表名。

补充:如果类名和数据表名不能直接对应,可以重写 [[yiidbActiveRecord::tableName()|tableName()]] 方法去显式指定相关表名。




使用 Country 类可以很容易地操作 country 表数据,就像这段代码:

use appmodelsCountry;

// 获取 country 表的所有行并以 name 排序
$countries = Country::find()->orderBy('name')->all();

// 获取主键为 “US” 的行
$country = Country::findOne('US');

// 输出 “United States”
echo $country->name;

// 修改 name 为 “U.S.A.” 并在数据库中保存更改
$country->name = 'U.S.A.';
$country->save();

补充:活动记录是面向对象、功能强大的访问和操作数据库数据的方式。你可以在活动记录章节了解更多信息。除此之外你还可以使用另一种更原生的称做数据访问对象的方法操作数据库数据。

创建操作






为了向最终用户显示国家数据,你需要创建一个操作。相比之前小节掌握的在 site 控制器中创建操作,在这里为所有和国家有关的数据新建一个控制器更加合理。新控制器名为CountryController,并在其中创建一个 index 操作,如下:

<?php

namespace appcontrollers;

use yiiwebController;
use yiidataPagination;
use appmodelsCountry;

class CountryController extends Controller
{
    public function actionIndex()
    {
        $query = Country::find();

        $pagination = new Pagination([
            'defaultPageSize' => 5,
            'totalCount' => $query->count(),
        ]);

        $countries = $query->orderBy('name')
            ->offset($pagination->offset)
            ->limit($pagination->limit)
            ->all();

        return $this->render('index', [
            'countries' => $countries,
            'pagination' => $pagination,
        ]);
    }
}

把上面的代码保存在 controllers/CountryController.php

index 操作调用了活动记录 Country::find() 方法,去生成查询语句并从 country 表中取回所有数据。为了限定每个请求所返回的国家数量,查询在 [[yiidataPagination]] 对象的帮助下进行分页。 Pagination 对象的使命主要有两点:

  • 为 SQL 查询语句设置 offset 和 limit 从句,确保每个请求只需返回一页数据(本例中每页是 5 行)。
  • 在视图中显示一个由页码列表组成的分页器,这点将在后面的段落中解释。




在代码末尾,index 操作渲染一个名为 index 的视图,并传递国家数据和分页信息进去。

创建视图



在 views 目录下先创建一个名为 country 的子目录。这个目录存储所有由 country 控制器渲染的视图。在 views/country 目录下创建一个名为 index.php 的视图文件,内容如下:

<?php
use yiihelpersHtml;
use yiiwidgetsLinkPager;
?>
<h1>Countries</h1>
<ul>
<?php foreach ($countries as $country): ?>
    <li>
        <?= Html::encode("{$country->name} ({$country->code})") ?>:
        <?= $country->population ?>
    </li>
<?php endforeach; ?>
</ul>

<?= LinkPager::widget(['pagination' => $pagination]) ?>

这个视图包含两部分用以显示国家数据。第一部分遍历国家数据并以无序 HTML 列表渲染出来。第二部分使用 [[yiiwidgetsLinkPager]] 去渲染从操作中传来的分页信息。小部件LinkPager 显示一个分页按钮的列表。点击任何一个按钮都会跳转到对应的分页。

尝试下



浏览器访问下面的 URL 看看能否工作:

http://hostname/index.php?r=country/index

国家列表

首先你会看到显示着五个国家的列表页面。在国家下面,你还会看到一个包含四个按钮的分页器。如果你点击按钮 “2”,将会跳转到显示另外五个国家的页面,也就是第二页记录。如果观察仔细点你还会看到浏览器的 URL 变成了:

http://hostname/index.php?r=country/index&page=2

在这个场景里,[[yiidataPagination|Pagination]] 提供了为数据结果集分页的所有功能:

  • 首先 [[yiidataPagination|Pagination]] 把 SELECT 的子查询 LIMIT 5 OFFSET 0 数据表示成第一页。因此开头的五条数据会被取出并显示。
  • 然后小部件 [[yiiwidgetsLinkPager|LinkPager]] 使用 [[yiidataPagination::createUrl()|Pagination::createUrl()]] 方法生成的 URL 去渲染翻页按钮。URL 中包含必要的参数 page 才能查询不同的页面编号。
  • 如果你点击按钮 “2”,将会发起一个路由为 country/index 的新请求。[[yiidataPagination|Pagination]] 接收到 URL 中的 page 参数把当前的页码设为 2。新的数据库请求将会以 LIMIT 5 OFFSET 5 查询并显示。

总结









本章节中你学到了如何使用数据库。你还学到了如何取出并使用 [[yiidataPagination]] 和 [[yiiwidgetsLinkPager]] 显示数据。

下一章中你会学到如何使用 Yii 中强大的代码生成器 Gii,去帮助你实现一些常用的功能需求,例如增查改删(CRUD)数据表中的数据。事实上你之前所写的代码全部都可以由 Gii 自动生成。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值