PHP程序员站--PHP编程开发平台
 当前位置:主页 >> PHP开源 >> PHP开源框架 >> 

Yii中文手册

Yii中文手册

来源:phperz.com  作者:phperz.com  发布时间:2011-12-01
Yii framework 中文手册 Yii 是什么 Yii 是一个基于组件、用于开发大型 Web 应用的高性能 PHP 框架。它将 Web 编程中的可重用性发挥到极致,能够显著加速开发进程。Yii(读作易)代表简单(easy)、高效(efficient)、可扩展(extensible)。 需求 要运行一个基于 Yii 开发

Yii framework 中文手册

Yii 是什么

Yii 是一个基于组件、用于开发大型 Web 应用的高性能 PHP 框架。它将 Web 编程中的可重用性发挥到极致,能够显著加速开发进程。Yii(读作“易”)代表简单(easy)、高效(efficient)、可扩展(extensible)。

需求

要运行一个基于 Yii 开发的 Web 应用,你需要一个支持 PHP 5.1.0 (或更高版本)的 Web 服务器。

对于想使用 Yii 的开发者而言,熟悉面向对象编程(OOP)会使开发更加轻松,因为 Yii 就是一个纯 OOP 框架。

Yii 适合做什么?

Yii 是一个通用 Web 编程框架,能够开发任何类型的 Web 应用。它是轻量级的,又装配了很好很强大的缓存组件,因此尤其适合开发大流量的应用,比如门户、论坛、内容管理系统(CMS)、电子商务系统,等等。

Yii 和其它框架比起来怎样?

和大多数 PHP 框架一样,Yii 是一个 MVC 框架。

Yii 以性能优异、功能丰富、文档清晰而胜出其它框架。它从一开始就为严谨的 Web 应用开发而精心设计,不是某个项目的副产品或第三方代码的组合,而是融合了作者丰富的 Web 应用开发经验和其它热门 Web 编程框架(或应用)优秀思想的结晶。

 

安装步骤

Yii 的安装由如下两步组成:

1.      从 yiiframework.com 下载 Yii 框架。

2.      将 Yii 压缩包解压至一个 Web 可访问的目录。

提示: 安装在 Web 目录不是必须的,每个 Yii 应用都有一个入口脚本,只有它才必须暴露给 Web 用户。其它 PHP 脚本(包括 Yii)应该保护起来不被 Web 访问,因为它们可能会被黑客利用。

需求

安装完 Yii 以后你也许想验证一下你的服务器是否满足使用 Yii 的要求,只需浏览器中输入如下网址来访问需求检测脚本:

http://hostname/path/to/yii/requirements/index.php

Yii 的最低需求是你的 Web 服务器支持 PHP 5.1.0 或更高版本。Yii 在 Windows 和 Linux 系统上的 Apache HTTP 服务器 中测试通过,应该在其它支持 PHP 5 的 Web 服务器和平台上也工作正常。

 

建立第一个 Yii 应用

为了对 Yii 有个初步认识,我们在本节讲述如何建立第一个 Yii 应用。我们将使用强大的 yiic 工具,它用来自动生成各种代码。假定 YiiRoot 为 Yii 的安装目录。

在命令行运行 yiic,如下所示:

% YiiRoot/framework/yiic webapp WebRoot/testdrive

注意: 在 MacOS、Linux 或 Unix 系统中运行 yiic 时,你可能需要修改 yiic 文件的权限使它能够运行。你也可以用 php YiiRoot/framework/yiic.php 来代替 yiic。

这将在 WebRoot/testdrive 目录下建立一个最基本的 Yii 应用,WebRoot 代表你的 Web 服务器根目录。这个应用具有所有必须的目录和文件,因此可以方便地在此基础上添加更多功能。

不用写一行代码,我们可以在浏览器中访问如下 URL 来看看我们第一个 Yii 应用:

http://hostname/testdrive/index.php

正如我们看到的,这个应用包含三个页面:首页、联系页、登录页。首页展示一些关于应用和用户登录状态的信息,联系页显示一个联系表单以便用户填写并提交他们的咨询,登录页允许用户先通过认证然后访问已授权的内容。查看下列截图了解更多:

首页

 
联系页

 
输入错误的联系页

 
提交成功的联系页

 
登录页

 
下面的树图描述了我们这个应用的目录结构。请查看约定以获取该结构的详细解释。

testdrive/

   index.php                 Web 应用入口脚本文件

   assets/                   包含公开的资源文件

   css/                      包含 CSS 文件

   images/                   包含图片文件

   themes/                   包含应用主题

   protected/                包含受保护的应用文件

      yiic                   yiic 命令行脚本

      yiic.bat               Windows 下的 yiic 命令行脚本

      commands/              包含自定义的 'yiic' 命令

         shell/              包含自定义的 'yiic shell' 命令

      components/            包含可重用的用户组件

         MainMenu.php        'MainMenu' 挂件类

         Identity.php        用来认证的 'Identity' 类

         views/              包含挂件的视图文件

            mainMenu.php     'MainMenu' 挂件的视图文件

      config/                包含配置文件

         console.php         控制台应用配置

         main.php            Web 应用配置

      controllers/           包含控制器的类文件

         SiteController.php  默认控制器的类文件

      extensions/            包含第三方扩展

      messages/              包含翻译过的消息

      models/                包含模型的类文件

         LoginForm.php       'login' 动作的表单模型

         ContactForm.php     'contact' 动作的表单模型

      runtime/               包含临时生成的文件

      views/                 包含控制器的视图和布局文件

         layouts/            包含布局视图文件

            main.php         所有视图的默认布局

         site/               包含 'site' 控制器的视图文件

            contact.php      'contact' 动作的视图

            index.php        'index' 动作的视图

            login.php        'login' 动作的视图

         system/             包含系统视图文件

连接到数据库

大多数 Web 应用由数据库驱动,我们的测试应用也不例外。要使用数据库,我们首先需要告诉应用如何连接它。修改应用的配置文件 WebRoot/testdrive/protected/config/main.php 即可,如下所示:

return array(

    ......

    'components'=>array(

        ......

        'db'=>array(

            'connectionString'=>'sqlite:protected/data/source.db',

        ),

    ),

    ......

);

在上面的代码中,我们添加了 db 条目至 components 中,指示应用在需要的时候连接到 SQLite 数据库 WebRoot/testdrive/protected/data/source.db。

注意: 要使用 Yii 的数据库功能,我们需要启用 PHP 的 PDO 扩展和相应的驱动扩展。对于测试应用来说,我们需要启用 php_pdo 和 php_pdo_sqlite 扩展。

接下来,我们需要准备一个 SQLite 数据库以使上面的配置生效。使用一些 SQLite 管理工具,我们可以建立一个包含如下模式的数据库:

CREATE TABLE User (

    id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,

    username VARCHAR(128) NOT NULL,

    password VARCHAR(128) NOT NULL,

    email VARCHAR(128) NOT NULL

);

简单起见,我们只在库中建立了一个 User 表。SQLite 数据库文件保存在 WebRoot/testdrive/protected/data/source.db。注意,数据库文件和包含它的目录都要求 Web 服务器进程可写。

实现 CRUD 操作

激动人心的时刻来了。我们想要为刚才建立的 User 表实现 CRUD (create, read, update 和 delete) 操作,这也是实际应用中最常见的操作。

我们还是用 yiic 工具来帮助我们生成需要的代码,这个过程通常称为“脚手架”。

% cd WebRoot/testdrive

% YiiRoot/framework/yiic shell

Yii Interactive Tool v1.0

Please type 'help' for help. Type 'exit' to quit.

>> model User

   generate User.php

 

The 'User' class has been successfully created in the following file:

    D:\wwwroot\testdrive\protected\models\User.php

 

If you have a 'db' database connection, you can test it now with:

    $model=User::model()->find();

    print_r($model);

 

>> crud User

   generate UserController.php

   generate create.php

      mkdir D:/wwwroot/testdrive/protected/views/user

   generate update.php

   generate list.php

   generate show.php

 

Crud 'user' has been successfully created. You may access it via:

http://hostname/path/to/index.php?r=user

如上所示,我们使用 yiic 的 shell 命令来和我们刚才建立的应用进行交互。在提示符后面,我们可以输入一个有效的 PHP 语句或表达式来运行并显示。我们还可以完成一些诸如 model 或 crud 之类的任务。model 命令自动生成一个基于 User 表结构的 User 模型类,crud 命令生成实现 User 模型 CRUD 操作的控制器类和视图。

注意: 如果你更改了你的任何代码或配置,请重新输入 yiic shell 以使你的新代码或配置文件生效。还有,确保你使用了正确的 PHP CLI 来运行 yiic,否则你会碰到 "...could not find driver" 之类的错误(即使你确信已经启用了 PDO 和相应的驱动)。这类错误通常是因为 PHP CLI 使用了不恰当的 php.ini。

让我们看看成果,访问如下 URL:

http://hostname/testdrive/index.php?r=user

这会显示一个 User 表中记录的列表。因为我们的表是空的,现在什么都没显示。

点击页面上的 新增用户 链接,如果没有登录的话我们将被带到登录页。登录后,我们看到一个可供我们添加新用户的表单。完成表单并点击 建立 按钮,如果有任何输入错误的话,一个友好的错误提示将会显示并阻止我们保存。回到用户列表页,我们应该能看到刚才添加的用户显示在列表中。

重复上述步骤以添加更多用户。注意,如果一页显示的用户条目太多,列表页会自动分页。

如果我们使用 admin/admin 作为管理员登录,我们可以在如下 URL 查看用户管理页:

http://hostname/testdrive/index.php?r=user/admin

这会显示一个包含用户条目的漂亮表格。我们可以点击表头的单元格来对相应的列进行排序,而且它和列表页一样会自动分页。

实现所有这些功能不要我们编写一行代码!

用户管理页

 
新增用户页

 
 

模型-视图-控制器 (MVC)

Yii 实现了 Web 编程中广为采用的“模型-视图-控制器”(MVC)设计模式。MVC 致力于分离业务逻辑和用户界面,这样开发者可以很容易地修改某个部分而不影响其它。在 MVC 中,模型表现信息(数据)和业务规则;视图包含用户界面中用到的元素,比如文本、表单输入框;控制器管理模型和视图间的交互。

除了 MVC,Yii 还引入了一个叫做 application 的前端控制器,它表现整个请求过程的运行环境。Application 接收用户的请求并把它分发到合适的控制器作进一步处理。

下图描述了一个 Yii 应用的静态结构:

Yii 应用的静态结构

 
一个典型的处理流程

下图描述了一个 Yii 应用处理用户请求时的典型流程:

Yii 应用的典型流程

 
1.      用户访问 http://www.example.com/index.php?r=post/show&id=1,Web 服务器执行入口脚本 index.php 来处理该请求。

2.      入口脚本建立一个应用实例并运行之。

3.      应用从一个叫 request 的应用组件获得详细的用户请求信息。

4.      在名为 urlManager 的应用组件的帮助下,应用确定用户要请求的控制器和动作。

5.      应用建立一个被请求的控制器实例来进一步处理用户请求,控制器确定由它的actionShow 方法来处理 show 动作。然后它建立并应用和该动作相关的过滤器(比如访问控制和性能测试的准备工作),如果过滤器允许的话,动作被执行。

6.      动作从数据库读取一个 ID 为 1 的 Post 模型。

7.      动作使用 Post 模型来渲染一个叫 show 的视图。

8.      视图读取 Post 模型的属性并显示之。

9.      视图运行一些挂件。

10.  视图的渲染结果嵌在布局中。

11.  动作结束视图渲染并显示结果给用户。

 

入口脚本
入口脚本是在前期处理用户请求的引导脚本。它是唯一一个最终用户可以直接请求运行的 PHP 脚本。

大多数情况下,一个 Yii 应用的入口脚本只包含如下几行:

// 部署到正式环境时去掉下面这行
defined('YII_DEBUG') or define('YII_DEBUG',true);
// 包含 Yii 引导文件
require_once('path/to/yii/framework/yii.php');
// 建立应用实例并运行
$configFile='path/to/config/file.php';
Yii::createWebApplication($configFile)->run();
这段代码首先包含了 Yii 框架的引导文件 yii.php,然后它配合指定的配置文件建立了一个 Web 应用实例并运行。

调试模式
一个 Yii 应用能够根据 YII_DEBUG 常量的指示以调试模式或者生产模式运行。默认情况下该常量定义为 false,代表生产模式。要以调试模式运行,在包含 yii.php 文件前将此常量定义为 true。应用以调试模式运行时效率较低,因为它会生成许多内部日志。从另一个角度来看,发生错误时调试模式会产生更多的调试信息,因而在开发阶段非常有用。

 

应用

应用是指执行用户的访问指令。其主要任务是解析用户指令,并将其分配给相应的控制器以进行进一步的处理。应用同时也是一个存储参数的地方。因为这个原因,应用一般被称为“前端控制器”。

入口脚本将应用创建为一个单例. 应用单例可以在任何位置通过 Yii::app() 来访问.

应用配置

默认情况下, 应用是 CWebApplication 类的一个实例. 要对其进行定制, 通常是在应用实例被创建的时候提供一个配置文件 (或数组) 来初始化其属性值. 另一个定制应用的方法就是扩展 CWebApplication 类.

配置是一个键值对的数组. 每个键名都对应应用实例的一个属性, 相应的值为属性的初始值. 举例来说, 下面的代码设定了应用的 名称 和 默认控制器 属性.

array(

    'name'=>'Yii Framework',

    'defaultController'=>'site',

)

我们一般将配置保存在一个单独的PHP代码里(e.g. protected/config/main.php). 在这个代码里,我们返回以下参数数组,

return array(...);

为执行这些配置,我们一般将这个文件作为一个配置,传递给应用的构造器。或者象下述例子这样传递给Yii::createWebApplication() 我们一般在 entry script里界定这些配置:

$app=Yii::createWebApplication($configFile);

提示: 如果应用配置非常复杂,我们可以将这分成几个文件,每个文件返回一部分配置参数。接下来,我们在主配置文件里用PHP include() 把其它 配置文件合并成一个配置数组。

应用的主目录

应用的主目录是指包含所有安全系数比较高的PHP代码和数据的根目录。在默认情况下,这个目录一般是入口代码所在目录的一个目录: protected 。这个路径可以通过在application configuration里设置 basePath来改变.

普通用户不应该能够访问应用文件夹里的内容。在 Apache HTTP 服务器里, 我们可以在这个文件夹里放一个 .htaccess 文件. .htaccess的文件内容是这样的:

deny from all

应用元件

我们可以很容易的通过元件(component)设置和丰富一个应用(Application)的功能。一个应用可以有很多应用元件,每个元件都执行一些特定的功能。比如说,一个应用可能通过CUrlManager 和 CHttpRequest部件来解析用户的访问。

通过配置 components property of application, 我们可以个性化一些元件的类及其参数。比如说,我们可以配置CMemCache 元件以便用服务器的内存当缓存。,

array(

    ......

    'components'=>array(

        ......

        'cache'=>array(

            'class'=>'CMemCache',

            'servers'=>array(

                array('host'=>'server1', 'port'=>11211, 'weight'=>60),

                array('host'=>'server2', 'port'=>11211, 'weight'=>40),

            ),

        ),

    ),

)

在上述例子中,我们将(缓存)cache元素(element)加在 元件 数组里. 这个 缓存(cache) 告诉我们这个元件的类是CMemCache 其服务 服务器(servers) 属性应该这样初始化。

要调用这个元件,用这个命令:Yii::app()->ComponentID,其中ComponentID是指这个元件的ID。 (比如 Yii::app()->cache).

我们可以在应用配置里,将enabled改为false来关闭一个元件。当我们访问一个被禁止的元件时,系统会返回一个NULL值。

提示: 默认情况下,应用元件是根据需要而创建的。这意味着一个元件只有在被访问的情况下才会创建。 因此,系统的整体性能不会因为配置了很多元件而下降。有些应用元件,(比如CLogRouter) 是不管用不用都要创建的。在这种情况下, 我们在应用的配置文件里将这些元件的ID列上:preload。

应用的核心元件

Yii预先定义了一套核心应用组件提供Web应用程序的常见功能。例如,request元件用于解析用户请求和提供信息,如网址,cookie。在几乎每一个方面,通过配置这些核心元件的属性,我们都可以更改Yii的默认行为。

下面我们列出CWebApplication预先声明的核心元件。

·        assetManager: CAssetManager -管理发布私有asset文件。

·        authManager: CAuthManager - 管理基于角色控制 (RBAC)。

·        cache: CCache - 提供数据缓存功能。请注意,您必须指定实际的类(例如CMemCache, CDbCache ) 。否则,将返回空当访问此元件。

·        clientScript: CClientScript -管理客户端脚本(javascripts and CSS)。

·        coreMessages: CPhpMessageSource -提供翻译Yii框架使用的核心消息。

·        db: CDbConnection - 提供数据库连接。请注意,你必须配置它的connectionString属性才能使用此元件。

·        errorHandler: CErrorHandler - 处理没有捕获的PHP错误和例外。

·        messages: CPhpMessageSource - 提供翻译Yii应用程序使用的消息。

·        request: CHttpRequest - 提供和用户请求相关的信息。

·        securityManager: CSecurityManager -提供安全相关的服务,例如散列(hashing), 加密(encryption)。

·        session: CHttpSession - 提供会话(session)相关功能。

·        statePersister: CStatePersister -提供全局持久方法(global state persistence method)。

·        urlManager: CUrlManager - 提供网址解析和某些函数。

·        user: CWebUser - 代表当前用户的身份信息。

·        themeManager: CThemeManager - 管理主题(themes)。

应用的生命周期

当处理一个用户请求时,一个应用程序将经历如下生命周期:

1.      建立类自动加载器和错误处理;

2.      注册核心应用组件;

3.      读取应用配置;

4.      用CApplication::init()初始化应用程序。

o        读取静态应用组件;

5.      触发onBeginRequest事件;

6.      处理用户请求:

o        解析用户请求;

o        创建控制器;

o        执行控制器;

7.触发onEndRequest事件;

 

控制器
控制器是 CController 或者其子类的实例. 用户请求应用时,创建控制器。控制器执行请求action,action通常引入必要的模型并提供恰当的视图。最简单的action仅仅是一个控制器类方法,此方法的名字以action开始。

控制器有默认的action。用户请求不能指定哪一个action执行时,将执行默认的action。缺省情况下,默认的action名为index。可以通过设置CController::defaultAction改变默认的action。

下边是最小的控制器类。因此控制器未定义任何action,请求时会抛出异常。

class SiteController extends CController
{
}
路由(Route)
控制器和actions通过ID标识的。控制器ID的格式: path/to/xyz对应的类文件protected/controllers/path/to/XyzController.php, 相应的 xyz应该用实际的控制器名替换 (例如 post 对应 protected/controllers/PostController.php). Action ID与 action 前辍构成 action method。例如,控制器类包含一个 actionEdit 方法, 对应的 action ID就是 edit。

注意: 在1.0.3版本之前, 控制器ID的格式是 path.to.xyz 而不是 path/to/xyz。

Users request for a particular controller and action in terms of route. A route is formed by concatenating a controller ID and an action ID separated by a slash. For example, the route post/edit refers to PostController and its edit action. And by default, the URL http://hostname/index.php?r=post/edit would request for this controller and action.

注意: By default, routes are case-sensitive. Since version 1.0.1, it is possible to make routes case-insensitive by setting CUrlManager::caseSensitive to be false in the application configuration. When in case-insensitive mode, make sure you follow the convention that directories containing controller class files are in lower case, and both controller map and action map are using keys in lower case.

Since version 1.0.3, an application can contain modules. The route for a controller action inside a module is in the format of moduleID/controllerID/actionID. For more details, see the section about modules.

控制器实例化
CWebApplication在处理一个新请求时,实例化一个控制器。程序通过控制器的ID,并按如下规则确定控制器类及控制器类所在位置

·         If CWebApplication::catchAllRequest is specified, a controller will be created based on this property, and the user-specified controller ID will be ignored. This is mainly used to put the application under maintenance mode and display a static notice page.

·         If the ID is found in CWebApplication::controllerMap, the corresponding controller configuration will be used to create the controller instance.

·         If the ID is in the format of 'path/to/xyz', the controller class name is assumed to be XyzController and the corresponding class file is protected/controllers/path/to/XyzController.php. For example, a controller ID admin/user would be resolved as the controller class UserController and the class file protected/controllers/admin/UserController.php. If the class file does not exist, a 404 CHttpException will be raised.

In case when modules are used (available since version 1.0.3), the above process is slighly different. In particular, the application will check if the ID refers to a controller inside a module, and if so, the module instance will be created first followed by the controller instance.

Action
As aforementioned, an action can be defined as a method whose name starts with the word action. A more advanced way is to define an action class and ask the controller to instantiate it when requested. This allows actions to be reused and thus introduces more reusability.

To define a new action class, do the following:

class UpdateAction extends CAction
{
    public function run()
    {
        // place the action logic here
    }
}
In order for the controller to be aware of this action, we override the actions() method of our controller class:

class PostController extends CController
{
    public function actions()
    {
        return array(
            'edit'=>'application.controllers.post.UpdateAction',
        );
    }
}
如上所示,使用路径别名application.controllers.post.UpdateAction 确定action类文件为protected/controllers/post/UpdateAction.php.

Writing class-based actions, we can organize an application in a modular fashion以模块方式组织程序。例如,可以使用下边的目录结构组织控制器代码:

protected/
    controllers/
        PostController.php
        UserController.php
        post/
            CreateAction.php
            ReadAction.php
            UpdateAction.php
        user/
            CreateAction.php
            ListAction.php
            ProfileAction.php
            UpdateAction.php
Filter
Filter is a piece of code that is configured to be executed before and/or after a controller action executes. For example, an access control filter may be executed to ensure that the user is authenticated before executing the requested action; a performance filter may be used to measure the time spent in the action execution.

An action can have multiple filters. The filters are executed in the order that they appear in the filter list. A filter can prevent the execution of the action and the rest of the unexecuted filters.

A filter can be defined as a controller class method. The method name must begin with filter. For example, the existence of the filterAccessControl method defines a filter named accessControl. The filter method must be of the signature:

public function filterAccessControl($filterChain)
{
    // call $filterChain->run() to continue filtering and action execution
}
where $filterChain is an instance of CFilterChain which represents the filter list associated with the requested action. Inside the filter method, we can call $filterChain->run() to continue filtering and action execution.

A filter can also be an instance of CFilter or its child class. The following code defines a new filter class:

class PerformanceFilter extends CFilter
{
    protected function preFilter($filterChain)
    {
        // logic being applied before the action is executed
        return true; // false if the action should not be executed
    }
 
    protected function postFilter($filterChain)
    {
        // logic being applied after the action is executed
    }
}
To apply filters to actions, we need to override the CController::filters() method. The method should return an array of filter configurations. For example,

class PostController extends CController
{
    ......
    public function filters()
    {
        return array(
            'postOnly + edit, create',
            array(
                'application.filters.PerformanceFilter - edit, create',
                'unit'=>'second',
            ),
        );
    }
}
The above code specifies two filters: postOnly and PerformanceFilter. The postOnly filter is method-based (the corresponding filter method is defined in CController already); while the PerformanceFilter filter is object-based. The path alias application.filters.PerformanceFilter specifies that the filter class file is protected/filters/PerformanceFilter. We use an array to configure PerformanceFilter so that it may be used to initialize the property values of the filter object. Here the unit property of PerformanceFilter will be initialized as 'second'.

Using the plus and the minus operators, we can specify which actions the filter should and should not be applied to. In the above, the postOnly should be applied to the edit and create actions, while PerformanceFilter should be applied to all actions EXCEPT edit and create. If neither plus nor minus appears in the filter configuration, the filter will be applied to all actions.

 

模型
模型是 CModel 或其子类的实例. 模型用于保持数据以及和数据相关的业务规则.

模型描述了一个单独的数据对象.它可以是数据表中的一行数据或者用户输入的一个表单.数据中的各个字段都描述了模型的一个属性.这些属性都有一个标签,都可以被一套可靠的规则验证.

Yii 从表单模型和 active record 实现了两种模型. 它们都继承自基类 CModel.

表单模型是CFormModel的实例.表单模型用于保存通过收集用户输入得来的数据.这样的数据通常被收集,使用,然后被抛弃.例如,在一个登录页面上,我们可以使用一个表单模型来描述诸如用户名,密码这样的由最终用户提供的信息.若想了解更多,请参阅 Working with Form

Active Record (AR) 是一种面向对象风格的,用于抽象数据库访问的设计模式.任何一个 AR 对象都是 CActiveRecord 或其子类的实例, 它描述的数据表中的单独一行数据.这行数据中的字段被描述成 AR 对象的一个属性. 关于 AR 的更多信息可以在 Active Record 中找到.

 

视图
视图是一个包含了主要的用户交互元素的PHP脚本.他可以包含PHP语句,但是我们建议这些语句不要去改变数据模型,且最好能够保持其单纯性(单纯作为视图)!为了实现逻辑和界面分离,大部分的逻辑应该被放置于控制器或模型里,而不是视图里.

视图有一个当其被渲染(render)时用于用于校验的名称.视图的名称与其脚本名称是一样的.例如:视图 edit 的名称出自一个名为 edit.php 的脚本文件.通过 CController::render() 调用视图的名称可以渲染一个视图.这个方法将在 protected/views/ControllerID 目录下寻找对应的视图文件.

在视图脚本内部,我们可以通过 $this 来访问控制器实例.我们可以在视图里以 $this->propertyName 的方式 pull 控制器的任何属性.

我们也可以用以下 push 的方式传递数据到视图里:

$this->render('edit', array(
    'var1'=>$value1,
    'var2'=>$value2,
));
在以上的方式中, render() 方法将提取数组的第二个参数到变量里.其产生的结果是,在视图脚本里,我们可以直接访问变量 $var1 和 $var2.

布局
布局是一种特殊的视图文件用来修饰视图.它通常包含了用户交互过程中常用到的一部分视图.例如:视图可以包含header和footer的部分,然后把内容嵌入其间.

......header here......
<?php echo $content; ?>
......footer here......
而 $content 则储存了内容视图的渲染结果.

当使用 render() 时,布局是固定的被提供的.视图脚本 protected/views/layouts/main.php 是默认的布局文件.它可以通过改变 CWebApplication::layout 或者 CWebApplication::layout 来实现定制 . 通过调用 renderPartial() 可以不依赖布局而渲染视图.

组件
组件是 CWidget 或其子类都实例.它是一个主要用于描述意图的组成部分.组件通常内嵌于一个视图来产生一些复杂却独立的用户界面.例如,一个日历组件可以用于渲染一个复杂的日历界面.组件可以在用户界面上更好的实现重用.

我们可以按如下视图脚本来使用一个组件:

<?php $this->beginWidget('path.to.WidgetClass'); ?>
...body content that may be captured by the widget...
<?php $this->endWidget(); ?>
或者

<?php $this->widget('path.to.WidgetClass'); ?>
后者用于不需要任何 body 内容的组件.

组件可以通过配置来定制它的表现.这些是通过调用 CBaseController::beginWidget 或者 CBaseController::widget 设置他们(组件)的初始化属性值来完成的.例如,当使用 CMaskedTextField 组件时,我们想指定被使用的 mask .我们通过传递一个携带这些属性初始化值的数组来实现.这里的数组的键是属性的名称,而数组的值则是组件属性所对应的值.正如以下所示 :

<?php
$this->widget('CMaskedTextField',array(
    'mask'=>'99/99/9999'
));
?>
继承 CWidget 以及重载它的init() 和 run() 方法,可以定义一个新的组件:

class MyWidget extends CWidget
{
    public function init()
    {
        // this method is called by CController::beginWidget()
    }
 
    public function run()
    {
        // this method is called by CController::endWidget()
    }
}
组件可以像一个控制器一样拥有它自己都视图.默认的,组件的视图文件位于包含了组件文件的 views 子目录之下.这些视图可以通过调用 CWidget::render() 渲染,这一点和控制器很相似.唯一不同的是,组件的视图没有布局文件支持.

系统视图
系统视图的渲染通常用于展示 Yii 的错误和日志信息.例如,当用户请求来一个不存在的控制器或动作时,Yii 会抛出一个异常来解释这个错误. 这时,Yii 就会使用一个特殊的系统视图来展示这个错误.

系统视图的遵从了一些规则.比如像 errorXXX 这样的名称就是用于渲染展示错误号 XXX 的 CHttpException 的视图.例如,如果 CHttpException 抛出来一个 404错误,那么 error404 就会被展示出来.

在 framework/views 下, Yii 提供了一系列默认的系统视图. 他们可以通过在 protected/views/system 下创建同名视图文件来实现定制.

 

部件
YII 应用构建于对象是规范编写的部件之上.部件是 CComponent 或其衍生类的实例.使用部件主要就是涉及访问其属性和挂起/处理它的事件.基类 CComponent 指定了如何定义属性和事件.

部件属性
组件的属性就像对象的公开成员变量.我们可以读取或设置组件属性的值.例如:

$width=$component->textWidth;     // 获取 textWidth 属性
$component->enableCaching=true;   // 设置 enableCaching 属性
我们可以简单的在组件类里公开声明一个公共成员变量来定义组件属性.更灵活的方法就是,如下所示的,定义 getter 和 setter 方法:

public function getTextWidth()
{
    return $this->_textWidth;
}
 
public function setTextWidth($value)
{
    $this->_textWidth=$value;
}
以上的代码定义了一个名称为 textWidth(大小写不敏感) 的可写属性.当读取属性时,getTextWidth()被请求,然后它它的返回值编程了属性的值;同样的,当写入属性石,setTextWidth() 被请求.如果 setter 方法没有定义,属性就是只读的如果向其写入将抛出一个异常.使用 getter 和 setter 方法来定义属性 有这样一个好处:当属性被读取或者写入的时候附加的逻辑(例如执行校验,挂起事件)可以被执行.

注意: 通过 getter/setter 方法和通过定位类里的一个成员变量来定义一个属性有一个微小的差异.前者大小写不敏感而后者大小写敏感.

部件事件
部件事件是一种特殊的属性,它可以将方法(称之为 事件句柄(event handlers))作为它的值.绑定(分配)一个方法到一个事件将会导致方法在事件被挂起处自动被调用.因此部件行为可能会被一种在部件开发过程中不可预见的方式修改.

部件事件以 on 开头的命名方式定义.和属性通过 getter/setter 方法来定义的命名方式一样,事件的名称是大小写不敏感的.以下方法定义了一个 onClicked 事件:

public function onClicked($event)
{
    $this->raiseEvent('onClicked', $event);
}
这里作为事件参数的 $event 是 CEvent 或其子类的实例.

我们可以按照下述为这个事件绑定一个方法:

$component->onClicked=$callback;
这里的 $callback 指向了一个有效的 PHP 回调.它可以是一个全局函数也可以是类中的一个方法.如果是后者他的提供方式必须是一个数组(array($object,'methodName')).

事件句柄必须按照如下来签署 :

function methodName($event)
{
    ......
}
这里的 $event 是描述事件(源于 raiseEvent() 调用的)的参数. $event 参数是 CEvent 或其子类的实例.它至少包含了"是谁挂起了这个事件"的信息.

如果我们现在调用了 onClicked(), onClicked 事件将被挂起(内置的 onClicked() ),然后被绑定的事件句柄将被自动调用.

一个事件可以绑定多个句柄.当事件被挂起时,句柄将会以他们被绑定到事件的先后顺序调用.如果句柄决定在调用期间防止其他句柄的调用,它可以设置 $event->handled 为 true.

部件行为
自 1.0.2 版起,部件开始支持 mixin 从而可以绑定一个或者多个行为.一个 行为(behavior) 就是一个对象,其方法可以被它绑定的部件通过收集功能的方式来实现 '继承(inherited)',而不是专有化继承(即普通的类继承).简单的来说,就是一个部件可以以'多重继承'的方式实现多个行为的绑定.

行为类必须实现 IBehavior 接口.大多数行为可以从 CBehavior 基类扩展而来.如果一个行为需要绑定到一个模型,它也可以从专为模型实现绑定特性的 CModelBehavior 或者 CActiveRecordBehavior 继承.

使用一个行为,首先通过调用行为的 attach() 方法绑定到一个部件是必须的.然后我们就可以通过部件调用行为了:

// $name 是行为在部件中唯一的身份标识.
$behavior->attach($name,$component);
// test() 是一个方法或者行为
$component->test();
一个已绑定的行为是可以被当作组件的一个属性一样来访问的.例如,如果一个名为 tree 的行为被绑定到部件,我们可以获得行为对象的引用:

$behavior=$component->tree;
// 相当于以下:
// $behavior=$component->asa('tree');
行为是可以被临时禁止的,此时它的方法开就会在部件中失效.例如:

$component->disableBehavior($name);
// 以下语句将抛出一个异常
$component->test();
$component->enableBehavior($name);
// 当前可用
$component->test();
两个同名行为绑定到同一个部件下是很有可能的.在这种情况下,先绑定的行为则拥有优先权.

当和 events 一起使用时,行为会更加强大.当行为被绑定到部件时,行为里的一些方法就可以绑定到部件的一些事件上了.这样一来,行为就有机观察或者改变部件的常规执行流程.

 

路径别名和命名空间

Yii 广泛的使用了路径别名.路径别名是和目录或者文件相关联的.它是通过使用点号(".")语法指定的,类似于以下这种被广泛使用的命名空间的格式:

RootAlias.path.to.target

RootAlias 则是一些已经存在目录的别名.通过调用 YiiBase::setPathOfAlias() 我们可以定义新的路径别名(包括根目录别名).

为了方便起见,Yii 预定义了以下根目录别名:

·        system: 指向 Yii 框架目录;

·        application: 指向应用程序 基本目录(base directory);

·        webroot: 指向包含里 入口脚本 文件的目录. 此别名自 1.0.3 版起生效.

·        module: 指向当前运行程序模型的目录. 此别名自 1.0.3 版起生效.

通过使用 YiiBase::getPathOfAlias(), 别名可以被转换成他的真实路径. 例如, system.web.CController 可以被转换成 yii/framework/web/CController.

使用别名来插入已定义的类是非常方便的.例如,如果我们想要包含 CController 类的定义, 我们可以通过以下方式调用:

Yii::import('system.web.CController');

import 方法不同于 include 和 require,它是更加高效的.实际上被导入(import)的类定义直到它第一次被调用之前都是不会被包含的. 同样的,多次导入同一个命名空间要比 include_once 和 require_once 快很多.

小贴士: 当调用一个通过 Yii 框架定义的类时, 我们不必导入或者包含它.所有的 Yii 核心类都是被预定义的.

我们也可以按照以下的语法导入整个目录,以便目录下所有的类文件都可以在需要时被包含.

Yii::import('system.web.*');

除了 import 外, 别名同样被用在其他很多地方来调用类.例如, 别名可以被传递到 Yii::createComponent() 创建的一个对应类的实例, 即使这个类文件没有被预先包含.

不要把别名和命名空间混淆了.命名空间调用了一些类名的逻辑分组以便他们可以同其他类名区分开,即使他们的名称是一样的,而别名则是用来引用类文件或者目录的.所以路径别名和命名空间并不冲突.

小贴士: 因为PHP 5.3.0以前的版本并不内置支持名命名空间,所以你并不能创建两个有着同样名称但是不同定义的类的实例.为此,所有 Yii 框架类都以字母 'C'(代表 'class') 为前缀,以便避免与用户自定义类产生冲突.在这里我们推荐为 Yii 框架保留'C'字母前缀的唯一使用权,用户自定义类则可以使用其他字母作为前缀.

 
延伸阅读:
Yii是什么

Tags: Yii   中文手册   手册  
最新文章
推荐阅读
月点击排行榜
PHP程序员站 Copyright © 2007-2010,PHPERZ.COM All Rights Reserved 粤ICP备07503606号