创建一个新的应用程序
要创建一个新的应用程序,我们将使用框架附带的一个小工具yiic,这是一个命令行工具,可以使你快速的建立一个全新的Yii应用。你不是必须要用此工具才能创建Yii应用,但使用它将节省你大量的时间,并保证文件及目录的结构。
要使用此工用创建Yii应用,需要打开一个shell窗口,并进入到系统的一个位置来创建应用程序
的目录结构。为了这个演示程序, 我们将确保如下要求:
• Yii的安装位置是你已经知道的
• WebRoot是你的Web服务器配置的根目录
• 从你的命令行,进入到WebRoot目录,并执行以下内容:
D:\xampp\htdocs> YiiRoot/framework/yiic webapp yiidemo
Create a Web application under 'D:\xampp\htdocs\yiidemo'? (yes|no)
Yes
mkdir /WebRoot/yiidemo
mkdir /WebRoot/yiidemo/assets
mkdir /WebRoot/yiidemo/css
generate css/bg.gif
generate css/form.css
generate css/main.css
你的应用已经成功创建到了'D:\xampp\htdocs\yiidemo'下。这个webapp命令的作用是创建一个全新的Yii
应用。它只需要指定一个参数,无论是绝对还是相对路径都会创建应用程序。它所生成的目录及
文件只是应用程序的一个骨架。
创建控制器
我们可以使用yii目录的shell或者使用已经生成的yiidemo目录下面的shell,两个所在目录分别是:
$ YiiRoot/framework/yiic shell 和 $ yiidemo/protected/yiic shell。
我们可以使用help查看shell所提供的所有命令列表,在使用help后,我们可以看到最后Example中输入的命令相同,但是执行的效果不同,原因是:
在最后两个例子中,使用的命令是一样的,但生成控制器所在的目录不同。Yii是能够检测出admin是一个模块还是一个子目录。
现在我们生成一个输出helloWorld的例子:
>> controller message helloWorld
它已经给出了创建成功的提示,MessageController默认创建到了protected/controllers/目录下。视图文件默认创建在protected/views/message/下。
控制器中数据传给视图
$this->render('helloWorld');
在render()方法这前,我们添加一段调用时间代码,将时间存入局域变量$theTime。然后我们添加render()方法的第二个参数,将$theTime这个变量传给redner()方法:
$theTime=date("D M j G:i:s T Y");
$this->render('helloWorld',array('time'=>$theTime));
法一:调用的render()方法第二个参数的数据是一个array(数组类型),render()方法会提取数组中的值提供给视图脚本,数组中的key(键值) 将是提供给视图脚本的变量名。在这个例子中,数组的key(键值) 是time,value(值) 是$theTime则提取出的变量名$time是供视图脚本使用的。这是将控制器的数据传递给视图的一种方法。
现在让我们在视图中使用这个变量而不使用date(日期函数)。再次打开helloWorld视图,
替换之前添加过的时间代码为:
<h3><?php echo $time; ?></h3>
法二:我们可以在控制器建立一个公共变量public $username ;然后在action里面设置值$this->username = '1221321Test;
在视图里面,我们可以直接调用输出:<?=$this->username?>
注:视图的文件名是不是一定要和控制器里面的ActionID一样呢?其实不然,请大家记住,这只是个推荐的命名约定。其实视图文件名不必与ActionID相同,只需要将文件的名字作为第一个参数传递给render()就可以了。
使用Yii的CHtml
这种情况可以使用Yii来处理,Yii提供了许多HTML助手,可在视图模板中使用。这些HTML助手都是以静态类的方式存在的。在当前的情况下,如何为应用程序配置URL结构呢?我们希望能过调用CHtml的link 方法,link 方法需要一个参数是controllerID/actionID成对出现的字符串,另一个超连接显示的名字。由于所有助手都是静态的,所以我们可以直接调用,而不需要创建它的实例。
例如:<p><?php echo CHtml::link("Goodbye",array('message/goodbye')); ?></p>
TrackStar:
在这一章中,我们将介绍一个项目任务跟踪系统,给它取了个名字叫TrackStar。目前世界上,已经有很多关于项目管理和问题跟踪的应用程序,我们的基本功能将没有什么与众不同。那么,为什么还要建立呢?事实证明,这种基于用户的应用程序有很多的功能,也是很常见的网络应用,这将使我们能够实现两个主要目的:
• 使用Yii自带的方便快捷的功能,建立可用的功能并挑战已经存在的其他网络应用。
• 介绍真实的示例和设计方案,这将帮助你可以快速建立属于你自己的Web应用。
单元测试和功能测试
单元测试的编写提供了验证代码是否正确。功能测试的编写提供了对应用程序整体的功能是否正
确。
Unit单元测试
单元测试是软件测试中最小的单位,在面向对象的应用程序中,(如Yii应用程序)的最小单位是类的接口,公共的方法。单元测试集中在一个单独的类中,而不要求与其它类或对象一起运行。他们的目的是为了验证一个最小单位的代码是否达到预期目的。
功能测试
功能测试重点测试应用程序端对端的功能特生。这个测试相对于单元测试要高一个层次,通常要多个类或对象一起运行。功能测试的目的是验证一个给定的应用程序功能是否可以正常工作。
测试驱动开发
测试驱动开发(TDD)是一种软件开发方法,它有助于为软件开发创造一个舒适和信心的环境,确保你的测试代码与你的应用程序一起成长,并始终保持最新。它规定在你开始写代码之前先写测试代码。下面是总结的步骤:
1. 开始写一个失败的测试代码。
2. 运行测试代码确定它是失败的。
3. 快速编写你的程序代码,并测试通过。
4. 再次运行测试代码,以确保它确实通过了。
5. 重构代码,移除重复的逻辑或改善某些部分,并试着测试通过。
在Yii中测试
从Yii1.1版本起,Yii已经紧密结合了PHPUnit(http://www.phpunit.de) 和Selenium Remote Control (http://seleniumhq.org/projects/remote-control/) 测试框架。特定的测试框架并没有关于TDD,但非常推荐使用。
当然,你可以使用测试框架测试Yii的PHP代码。然而,Yii已经与前面提到的两个框架紧密集成,所以使事情变的更简单。因为简单,所以我们首要目标是使用Yii的测试功能。
在第2章中,当我们使用yiic webapp命令创建Hello,World应用程序时,我们注意到,我们创建了许多文件和文件夹。以下是自动测试相关的:
Name of folder Use/contents
demo/
protected This contains protected application files
tests/ This contains tests for application
fixtures/ This contains databases fixtures
functional/ This contains functional tests
unit/ This contains unit tests
report/ This contains coverage reports
bootstrap.php The script executed at the very beginning of the tests
phpunit.xml The PHPUnit configuration file
WebTestCase.php The base class for Web-based functional tests
我们将我们的测试文件放到这个主要目录:fixtures,functional,unit。这些报告文件夹用于存储生成的代码覆盖率的报告。
功能测试
与单元测试一样,功能测试也是编写一个PHP类。但它是继承自己CWebTestCase类,而不是CTestCase类。跟据约定,如果我们的测试类名叫AbcTest,其中Abc是被测试的类,则测试类的文件名叫AbcTest.php只存在protected/tests/functional中。
为了运行功能测试,你需要安装Selenium。
安装Selenium
除了PHPUnit,Selenium Remote Control Server (Selenium RC)是为了运行功能测试所需要的。
安装Selenium Rc非常简单。
1. 从http://seleniumhq.org/download/下载Selenium Remote Control Server (Selenium RC)zip文件
2. 解压zip文件到你的系统中。
在解压后的目录中,有几个是基础于客户端的目录和一个包含Selenium RC Server的目录,它的名字有点类似selenium-server-1.0.x/。其中的x是具体的下载版本。启动服务器也非常简单。只要在命令行下进入服务器文件所在目录,运行以下命令:
% java -jar selenium-server.jar它将在命令行下启动服务。
安装PHPUnit
为了继续往下进行单元测试,您需要安装PHPUnit。应该使用Pear安装(获得更多关于Pear的信息,请访问http://pear.php.net),如Mac OS(苹果操作系统)用户,只需如下两条命令:
% sudo pear channel-discover pear.phpunit.de
% sudo pear install phpunit/PHPUnit
安装方法(也适用Window,进入php目录存在pear命令):
sudo apt-get remove phpunit
sudo pear channel-discover pear.phpunit.de
sudo pear channel-discover pear.symfony-project.com
sudo pear channel-discover components.ez.no
sudo pear update-channels
sudo pear upgrade-all
sudo pear install --alldeps phpunit/PHPUnit
sudo pear install --force --alldeps phpunit/PHPUnit
安装后后可能会报错如下:
Fatal error: require_once(): Failed opening required 'PHPUnit/Extensions/SeleniumTestCase.php' (include_path='.;D:\xampp\php\pear') in D:\xampp\htdocs\yii\framework\test\CWebTestCase.php on line 12
缺少一个文件包,我们需要安装上:pear install phpunit/PHPUnit_Selenium
关于PHPUnit测试功能使用已经超出了本书范围,建议你花一些时间阅读一下文档(http://www.phpunit.de/wiki/Documentation),并学习如何编写一个基础本的单元测试。
单元测试
在Yii是中编写单元测试是从框架类CTestCase中继承一个PHP类。跟据约定,这个类被命名为AbcTest,其中Abc可以被替换成试测类的名称。
例如,第2章的示例程序,如果我们要测试Message类,则测试类的名称是MessageTest。这个类是保存在protected/tests/unit/下,文件名是MessageTest.php。
测试类中主要包括测试的操作方法,名字是testXyz,其中Xyz经常与这个测试类相对的类的操作方法名称。
继续MessageController的例子,如果我们测试Helloworld()方法,则在MessageTest类中的测试方法是testHelloWorld()。
开始使用phpunit测试(TDD)
我们首先在yiidemo/protected/tests/unit/下面建立一个测试文件:MessageTest.php(这个文件是对MessageController.php进行测试)并写入如下代码testRepeat()方法是对MessageController.php里面的repeat方法进行测试。
<?php
class MessageTest extends CTestCase {
function testRepeat()
{
}
}
?>
然后$ cd yiidemo/protected/tests目录,执行命令$ phpunit unit/MessageTest.php 。由于我们没有写任何逻辑代码在文件里面,所以最后会出现:
Time: 0 seconds, Memory: 3.00Mb
OK (1 test, 0 assertions)
现在我们开始编写代码,验证返回的字符串是否与传入的字符串相同。
<?php
Yii::import('application.controllers.MessageController');
class MessageTest extends CTestCase{
function testRepeat()
{
$message = new MessageController('MessageTest');
$text = "Hello,Any One Out there?";
$returnMessage = $message->repeat($text);
$this->assertEquals($returnMessage,$text);
}
}
?>
我们建新一个MessageController类的实例,并提供一个用来验证的controllerId 传给构造函数。然后我们定义一个字符串变量$text ,并传给repeat() 方法,并将返回结果保存在函数返回的$returnMessage变量中。
正如我们期望所返回的信息中包含完全相同的字符串。我们使用PHPUnit的API方法assertEquals()用来比较第一个字符串与第二个字符串的结果是否相等(或真或假)。现在这个测试用例已经写完了,让我们试着运行它:
注:一定要记得把MessageController这个类导入进来,不然不能实例化,我们可以使用Yii::import语法来包含MessageController类。
Yii::import方法允许我们快速包含一个定义的类。它不同与include和require,因为它很高效。这个定义类开始导入时其实并没有包含,直到它首次被引用时才包含。多次导入同一个定义类也要比include_once 和require_once快的多。注意:当提到一个Yii框架内定义类,我们不需要导入或包含它,因为所有YIi的核心类已经预先导入了。
如果你刚刚接触TDD,这一切看起来有点奇怪,特别是要考虑所有细节,有时可能很小的细节只是为了实现这样一个普通的方法。这主要是为了帮助你理解TDD的流程和节奏。控制这个细节的大小是TDD的一门艺术。开始的细节可以很小,后面再放大,这样你会感觉很舒服也更加有信心。
提供给开发者几个在测试框架中需要了解的知识。测试结果通过以彩色编码显示。通过测试显示绿色,测试失败显示红色。这种方式也有点像马路上的红绿灯。TDD常常强调:红(Red),绿(Green),重构(Refactor),重复(Repeat)。这是指的基本步骤,如下:
1. 红色:快速添加一个新的测试用例,然后运行,并看到测试失败。
2. 绿色:做一个小小的改动,只要能满足测试通过就可以。
3. 重构:如有必要,删除代码中任何重复的地方,你做这么是否为了让测试能够快速通过,但在其他方面可能也会让你不妥。
4. 重复:重复第1步。
创建初始应用---连接数据库(YII):
测试数据库
在前面中,我们已经了解了Yii提供的测试框架。所以,我们知道在protected/tests/unit/下添加一个测试文件,让我们在这个目录下创建一个简单的测试数据库连接的测试文件DbTest.php。并添加如下内容:
<?php
class DbTest extends CTestCase{
function testConnection()
{
$this->assertTrue(true);
}
}
?>
在这里,我们添加了一个非常普通的测试代码,assertTrue()方法是PHPUnit中定义的,断言是如果参数为true将通过,false 则失败。因此,在这种情况下,它传的是true所以这个测试会通过。我们编写测试文件做是为了确保我们新的应用程序工作正常。进入测试目录,并执行这个新的测试:
如果由于某种原因,在你的系统测试失败,你可能需要修改protected/tests/bootstrap.php中的变量$yiit正确指向your/YiiRoot/yiit.php。
相信在新建的TrackStar应用程序中测试文件已经可以运行了,下面我们可以测试一个数据库连接。
修改testConnection方法中的assertTrue(true)语句为如下代码:
$this->assertNotEquals(NULL, Yii::app()->db);
这个测试是假设应用程序已经配置了数据库连接组件db。(后面我们将会讨论更多关于应用程序组件问题)。该测式断言,当应用程序与db连接时,其结果不为空值。事实上,自动创建的应用程序已经使用了一个数据库,使用yiic工具生成的应用程序为我们配置了一个SQLite数据库。你可以查看protected/config/main.php文件,大约在中间部份有如下声明:
'db'=>array(
'connectionString' =>
'sqlite:'.dirname(__FILE__).'/../data/yiibook.db',
),
Yii和数据库
Yii数据访问对象(DAO)是建立在PHP数据对象(PDO)扩展(http://php.net/pdo)基础之上。应用程序使用Yii中的DAO可以很容易地切换使用不同的DBMS。要建立一个支持DBMS的连接,可以简单的实例化CDbConnection类:
$connection=new CDbConnection($dsn,$username,$password);
这里$dsn的变量的格式取决于具体被使用程序所采用的PDO驱动程序。一些常见的格式包括:
• SQLite:sqlite:/path/to/dbfile
• MySQL:mysql:host=localhost;dbname=testdb
• PostgreSQL:pgsql:host=localhost;port=5432;dbname=testdb
• SQL Server:mssql:host=localhost;dbname=testdb
• Oracle:oci:dbname=//localhost:1521/testdb
应用程序的配置文件
当应用程序实例被创建时初始化它的属性,这个主应用程序的配置文件位于/protected/config/main.php。
配置Mysql数据库文件
'db'=>array(
'connectionString' => 'mysql:host=127.0.0.1;dbname=yiitest',
'emulatePrepare' => true,
'username' => 'your_db_user_name',
'password' => 'your_db_password',
'charset' => 'utf8',
),
emulatePrepare=>true这个配置设置一个PDO属性(PDO::ATTR_EMULATE_PREPARES) 为true,建议如你使用PHP5.1.3或更高版本。
其中一个很大的好处是从现在起可以使用这个应用组件,我们可以参考数据库连接作为Yii主程序的一个属性Yii:app()->db 可以使用在我们应用程序中的任何位置。同样,我们可以将任何组件的配置定义在配置文件中。
CRUD的操作:
创建一个用来测试的表:
CREATE TABLE tbl_project
(
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(128),
description TEXT,
create_time DATETIME,
create_user_id INTEGER,
update_time DATETIME,
update_user_id INTEGER
);
表名命名规则
在我们的开发中,我们将所有表名和列名都使用小写字母。
Yii中为了采用表前缀支持,必须设置CDbConnection::tablePrefix属性为期望的表前缀。然后在整个应用程序的SQL语句中,可以使用{{TableName}} 做为参考表名,其中TableName就是表的名称,但不用前缀。
配置Gii
从1.1.2版本起,Yii有一个新的和更复杂的界面工具Gii。Gii是一个高度可定制和可扩展的基础于Web的代码生成平台,把yiic shell命令提升到了新的高度。我们将使用这个新平台,创建我们的新模型类。
打开配置文件:proctected/config/main.php,然后找到modules,输入以下code:
'gii'=>array(
'class'=>'system.gii.GiiModule',
'password'=>'Enter Your Password Here',
// If removed, Gii defaults to localhost only. Edit carefully to taste.
'ipFilters'=>array('127.0.0.1','::1'),
),
通过如下命令访问,密码就是你配置的密码:http://127.0.0.1/yiidemo/index.php?r=gii/default/login
使用Gii创建项目(project)AR类
在进入gii页面,可以看到所有的选项与使用$ yiic shell命令行帮助显示出来的是一样的,现在我们需要创建一个Model。
如果您使用一个前缀tbl,你可以在此添加。指定此值将意味着我们新生成的AR类将被命名为Project,而不是tbl_project。
接下来的两个字段域是要求输入表名和我们希望生成的类名。我们表的名称是tbl_project。模型类它使用表名但没有前缀,并以大写字母开头来。因此,Project为我们模型类的名称。
Base Class字段用来指定继承哪个模型类。这个类是CActiveRecord或它的子类。
Model Path字段类允许你指定这个模型类文件在应用程序中的位置。
Code Template字段指定使用的生成器的模板。我们可以自定义默认模板以应对其它可能出现的情况,比如所有的模型需要有共同的需求。
Gii已经为我们创建了一个新的AR模型类。它的名字是Project.php,默认情况下,放在protected/models/目录。这个类封装了是我们的tbl_project 表。表中的所有字段访问是通过Project AR类的属性。
创建单元测试文件
首先,需要创建一个新的单元测试文件,让我们创建这个文件在:protected/tests/unit/ProjectTest.php,并输入如下代码:
<?php
class ProjectTestextends CDbTestCase
{
public function testCRUD()
{
}
}
这个类继承自CDbTestCase,这是Yii框架中单测元类的基类,最门用来测试与数据库相关的功能。这个特定的基类提供了一些管理操作。下面我们将介绍更多的细节。
插入(Create)
function testCURD()
{
//Create a new project
$newProject=new Project;
$newProjectName = 'Test Project 1';
$newProject->setAttributes(
array(
'name' => $newProjectName,
'description' => 'Test project number one',
'create_time' => '2010-01-01 00:00:00',
'create_user_id' => 1,
'update_time' => '2010-01-01 00:00:00',
'update_user_id' => 1,
)
);
$this->assertTrue($newProject->save(false));
}
我们传递给save()方法一个参数false,用来告诉它绕过属性的数据验证(我们将在数据模型验证部份介绍它,添加自己的验证字段)。然后我们测试返回值,保存成功将返回true。
读取(Read)
使用phpunit进行检测,首先我们插入一个数据,然后通过返回的id得到所有刚刚插入的数据,最后判断我们插入的名字和得到的名字是不是相同的。
function testCURD()
{
//Create a new project
$newProject=new Project;
$newProjectName = 'Test Project 2';
$newProject->setAttributes(
array(
'name' => $newProjectName,
'description' => 'Test project number one',
'create_time' => '2010-01-01 00:00:00',
'create_user_id' => 1,
'update_time' => '2010-01-01 00:00:00',
'update_user_id' => 1,
)
);
$this->assertTrue($newProject->save(false));
//Read the insert data
$projectModel = Project::model()->findByPk($newProject->id);
$this->assertTrue($projectModel instanceof Project);
$this->assertEquals($newProjectName,$projectModel->name);
}
在这里,我们使用静态方法model(),它已经定义在了每一个AR类中。这个方法返回了Project AR类的实例,从而进行内部访问该类的方法。
测试更新(Update)和删除(Delete)
function testCURD()
{
//Create a new project
...
//Read the insert data
...
//UPDATE the newly created project
$updatedProjectName = 'Updated Test Project 1';
$newProject->name = $updatedProjectName;
$this->assertTrue($newProject->save(false));
//read back the record again to ensure the update worked
$updatedProject=Project::model()->findByPk($newProject->id);
$this->assertTrue($updatedProject instanceof Project);
$this->assertEquals($updatedProjectName,$updatedProject->name);
//DELETE the project
$newProjectId = $newProject->id;
$this->assertTrue($newProject->delete());
$deletedProject=Project::model()->findByPk($newProjectId);
$this->assertEquals(NULL,$deletedProject);
}
在这里,我们增加了用来测试项目(project) 的更新和删除的代码。首先,我们给$newProject实例更新name属性。由于这里的AR实例已经存在,我们知道这个,AR类是更新,而不是插入新记录,当我们调用->save()后,我们再读回这行,来确定是否更新
了name。
为了测试删除,我们保存$newProject实例的id 属性值到一个局部变量$newProjectId。然后,我们调用$newProject实例的->delete() 方法。然后我们尝试通过这个$newProjectId作为主键,查询Project返回这行。由于这条记录已经被删除,我们将得到的结果为NULL。测试断言将使用NULL比较。
通过脚手架为项目创建 CRUD
进入gii并选中Crud Generator。我们看到两个表单字段域。第一个是要求我们指定模型类,我们希望生成所有的 CRUD 操作。在我们的例子中,使用 Project.php 这个 AR 类。所以在这个字段域中填写 Project。当我 们输入后,我们注意到,Controller ID 字段域自动填充成了 project,这是基于 Yii 的约定。我们 现在保持默认即可。
我们可以看到将要生成很多的文件,其实包括一个 ProjectContrller.php 控制器类文件(它的包 括了 CRUD 的所有操作方法)和许多的视图文件,每一个单独的视图文件对应每一个操作同时 提供了可以搜索项目 (project) 记录。你当然也可以通过去掉复选框的选择来不生成一些相应文 件。然后,对我们而言,我们很喜欢 Gii 为我们创建的这些文件。
为表单添加必填字段域
在YII中表单与AR模型交互时,我们可以设置一个验证规则来限制字段域的范围。我们在Project AR模型类的rules()方法中,添加一个数组,数组包含特定的值。
打开/protected/models/Project.php 类,已经看到了公共的 rules 方法被定义了,并且在 rules方法中已经存在了一些规则。
rules() 方法返回的是一个规则数组,一般每一个规则格式如下所示:
Array('Attribute List', 'Validator', 'on'=>'Scenario List',additional options) 相关属性解释如下:
Attribute List(属性列表) 是一个字符串,需要验证的类的属性名用逗号分开。
Validator(验证器) 指的是使用什么样的规则执行验证。
on 这个参数指定了一个 scenario(情景) 列表来使用这条验证规则。
注:scenario(情景) 允许你限制验证规则应用在特定的上下文中。一种典型的例子 是 insert(插入) 或 update(更新)。例如:如果被指定为 ‘on’=>’insert’,这将表 明验证规则只适用于模型的插入情景。这同样适用于’update’ 或其它的任何你 希望定义的情景。你可以设置一个模型的 scenario(情景) 属性或通过构造函数传给一个模型的实例。
additional options(附加选项) 是 name/value(键值对) 出现的,用来初始化 validator(验证器) 的属性。
validator(验证器) 可以是模型类中的一个方法或一个单独的验证器类。如果定义为模型类中的方 法,它的格式必须是如下的形式:
public function ValidatorName($attribute,$params) { … }
如果我们使用一个 validator(验证器) 类,则这个类必须继承 CValidator。其实有三种方法可以指
定validator(验证器),包括前面提到的一种格式:
1. 第一种是在模型类中定义验证方法
2. 第二种是指定一个单独的验证器类(这个类继承 CValidator)。
3. 第三种是你可以使用 Yii 框架中现有的验证器,指定预定义的验证器别名即可。
Yii 为你提供了很多预定义的验证器类,同时也指定了别名,用在定义规则时。Yii1.1 版本,预定义的验证器别名的完整列表如下:
• boolean:它是 CBooleanValidator 类的别名,验证属性的值是布尔值 (true 或 false)。
• captcha:它是 CCaptchaValidator 类的别名,验证属性的值等于一个显示的CAPTCHA(验
证码) 的值。
• compare:它是 CCompareValidator 类的别名,验证属性的值与另一个属性的值相等。
• email:它是 CEmailValidator 类的别名,验证属性的值为有一个有效的 Email 地址。
• default:它是 CDefaultValidator 类的别名,验证属性的值为分配的默认值。
• exist:它是 CExistValidator 类的别名,验证属性的值在表中的对应列中存在。
• file:它是 CFileValidator 类的别名,验证属性的值包含上传的文件。
• filter:它是 CFilterValidator 类的别名,用过滤器转换属性的值。
• in:它是 CRangeValidator 类的别名,验证属性值在一个预定义列表中。
• length:它是 CStringValidator 类的别名,验证属性值的长度在一个范围内。
• match:它是 CRegularExpressionValidator 类的别名,验证属性值匹配一个正则表达式。
• numerical:它是 CNumberValidator 类的别名,验证属性值是数字。
• required:它是 CRequiredValidator 类的别名,验证属性值必需有值,不能为空。
• type:它是 CTypedValidator 类的别名,验证属性值是一个指定的数据类型。
• unique:它是 CUniquedValidator 类的别名,验证属性值在表中的对应列中是唯一的。
• url:它是 CUrlValidator 类的别名,验证属性值是一个有效的 URL。
所以知道了上面的信息后,如果我想增加一个新的验证规则,名字必填的话,可以这样在rules里写:
return array(
…
//array('name', 'required'),
//name 和 description都必填
array('name, description', 'required'),
…
);