Yii中表单用法实例详解
|
本文实例讲述了Yii中表单用法。分享给大家供大家参考,具体如下: 在 Yii 中处理表单时,通常需要以下步骤: 1. 创建用于表现所要收集数据字段的模型类。 2. 创建一个控制器动作,响应表单提交。 3. 在视图脚本中创建与控制器动作相关的表单。 一、创建模型在编写表单所需的 HTML 代码之前,我们应该先确定来自最终用户输入的数据的类型,以及这些数据应符合什么样的规则。模型类可用于记录这些信息。正如模型章节所定义的,模型是保存用户输入和验证这些输入的中心位置。 取决于使用用户所输入数据的方式,我们可以创建两种类型的模型。如果用户输入被收集、使用然后丢弃,我们应该创建一个表单模型; 如果用户的输入被收集后要保存到数据库,我们应使用一个Active Record。两种类型的模型共享同样的基类 CModel,它定义了表单所需的通用接口。 1、定义模型类例如创建为一个表单模型: LoginForm中定义了三个属性: $username,$password 和$rememberMe。他们用于保存用户输入的用户名和密码,还有用户是否想记住他的登录的选项。由于 $rememberMe 有一个默认的值false,相应的选项在初始化显示在登录表单中时将是未勾选状态。 我们将这些成员变量称为特性(attributes)而不是属性(properties),以区别于普通的属性(properties)。特性(attribute)是一个主要用于存储来自用户输入或数据库数据的属性(propertiy)。 2、声明验证规则一旦用户提交了他的输入,模型被填充,我们就需要在使用前确保用户的输入是有效的。这是通过将用户的输入和一系列规则执行验证实现的。我们在 rules() 方法中指定这些验证规则,此方法应返回一个规则配置数组。 _identity=new UserIdentity($this->username,$this->password); if(!$this->_identity->authenticate()) $this->addError('password','错误的用户名或密码。'); } }rules() 返回的每个规则必须是以下格式: 代码如下:'ScenarioList',...附加选项) 其中: AttributeList(特性列表)是需要通过此规则验证的特性列表字符串,每个特性名字由逗号分隔; Validator(验证器) 指定要执行验证的种类; on 参数是可选的,它指定此规则应被应用到的场景列表; 附加选项 是一个名值对数组,用于初始化相应验证器的属性值。 有三种方式可在验证规则中指定 Validator: 第一, Validator 可以是模型类中一个方法的名字,就像上面示例中的 authenticate 。验证方法必须是下面的结构: 代码如下: 第三,Validator 可以是一个预定义的验证器类的别名。在上面的例子中,required 名字是 CRequiredValidator 的别名,它用于确保所验证的特性值不为空。下面是预定义的验证器别名的完整列表: boolean: CBooleanValidator 的别名,确保特性有一个 CBooleanValidator::trueva lue 或 CBooleanValidator::falseva lue 值。 captcha: CCaptchaValidator 的别名,确保特性值等于 CAPTCHA 中显示的验证码。 compare: CCompareva lidator 的别名,确保特性等于另一个特性或常量。 email: CEmailValidator 的别名,确保特性是一个有效的Email地址。 default: CDefaultValueva lidator 的别名,指定特性的默认值。 exist: CExistValidator 的别名,确保特性值可以在指定表的列中可以找到。 file: CFileva lidator 的别名,确保特性含有一个上传文件的名字。 filter: CFilterValidator 的别名,通过一个过滤器改变此特性。 in: CRangeva lidator 的别名,确保数据在一个预先指定的值的范围之内。 length: CStringValidator 的别名,确保数据的长度在一个指定的范围之内。 match: CRegularExpressionValidator 的别名,确保数据可以匹配一个正则表达式。 numerical: CNumberValidator 的别名,确保数据是一个有效的数字。 required: CRequiredValidator 的别名,确保特性不为空。 type: CTypeva lidator 的别名,确保特性是指定的数据类型。 unique: CUniqueva lidator 的别名,确保数据在数据表的列中是唯一的。 url: CUrlValidator 的别名,确保数据是一个有效的 URL。 下面我们列出了几个只用这些预定义验证器的示例: 3,'max'=>12),// 在注册场景中,密码password必须和password2一致。 array('password','compare','compareAttribute'=>'password2','on'=>'register'),// 在登录场景中,密码必须接受验证。 array('password','authenticate','on'=>'login'),3、安全的特性赋值在一个类的实例被创建后,我们通常需要用最终用户提交的数据填充它的特性。这可以通过如下块赋值(massive assignment)方式轻松实现: attributes=$_POST['LoginForm'];最后的表达式被称作 块赋值(massive assignment) ,它将 $_POST['LoginForm'] 中的每一项复制到相应的模型特性中。这相当于如下赋值方法: $value) { if($name 是一个安全的特性) $model->$name=$value; }检测特性的安全非常重要,例如,如果我们以为一个表的主键是安全的而暴露了它,那么攻击者可能就获得了一个修改记录的主键的机会,从而篡改未授权给他的内容。 特性如果出现在相应场景的一个验证规则中,即被认为是安全的。例如: 'login,register'),array('email',如上所示, username 和 password 特性在 login 场景中是必填项。而 username,password 和 email特性在 register 场景中是必填项。于是,如果我们在 login 场景中执行块赋值,就只有 username 和 password会被块赋值。因为只有它们出现在 login 的验证规则中。另一方面,如果场景是 register ,这三个特性就都可以被块赋值。 attributes=$_POST['User']; // 在注册场景中 $model=new User('register'); if(isset($_POST['User'])) $model->attributes=$_POST['User'];那么为什么我们使用这样一种策略来检测特性是否安全呢?背后的基本原理就是:如果一个特性已经有了一个或多个可检测有效性的验证规则,那我们还担心什么呢? 请记住,验证规则是用于检查用户输入的数据,而不是检查我们在代码中生成的数据(例如时间戳,自动产生的主键)。因此,不要为那些不接受最终用户输入的特性添加验证规则。 有时候,我们想声明一个特性是安全的,即使我们没有为它指定任何规则。例如,一篇文章的内容可以接受用户的任何输入。我们可以使用特殊的 safe 规则实现此目的: 代码如下: 还有一个用于声明一个属性为不安全的 unsafe 规则: 代码如下: unsafe 规则并不常用,它是我们之前定义的安全特性的一个例外。 4、触发验证一旦模型被用户提交的数据填充,我们就可以调用 CModel::validate() 触发数据验证进程。此方法返回一个指示验证是否成功的值。对CActiveRecord 模型来说,验证也可以在我们调用其 CActiveRecord::save() 方法时自动触发。 我们可以通过设置scenario属性来设置场景属性,这样,相应场景的验证规则就会被应用。 验证是基于场景执行的。 scenario属性指定了模型当前用于的场景和当前使用的验证规则集。例如,在 login 场景中,我们只想验证用户模型中的username 和 password 输入;而在 register 场景中,我们需要验证更多的输入,例如 email,address,等。下面的例子演示了如何在 register 场景中执行验证: scenario='register'; $model=new User('register'); //给模型类添加参数,该参数就是要触发的验证场景 // 将输入的值填充到模型 $model->attributes=$_POST['User']; // 执行验证 if($model->validate()) // 如果输入有效 ... else ...规则关联的场景可以通过规则中的 on 选项指定。如果 on 选项未设置,则此规则会应用于所有场景。例如: 第一个规则将应用于所有场景,而第二个将只会应用于 register 场景。 5、提取验证错误验证完成后,任何可能产生的错误将被存储在模型对象中。我们可以通过调用 CModel::getErrors()和CModel::getError() 提取这些错误信息。这两个方法的不同点在于第一个方法将返回所有 模型特性的错误信息,而第二个将只返回第一个 错误信息。 6、特性标签当设计表单时,我们通常需要为每个表单域显示一个标签。标签告诉用户他应该在此表单域中填写什么样的信息。虽然我们可以在视图中硬编码一个标签,但如果我们在相应的模型中指定(标签),则会更加灵活方便。 默认情况下 CModel 将简单的返回特性的名字作为其标签。这可以通过覆盖 attributeLabels() 方法自定义。正如在接下来的小节中我们将看到的,在模型中指定标签会使我们能够更快的创建出更强大的表单。 二、创建动作有了模型,我们就可以开始编写用于操作此模型的逻辑了。我们将此逻辑放在一个控制器的动作中。对登录表单的例子来讲,相应的代码就是: attributes=$_POST['LoginForm']; // 验证用户输入,并在判断输入正确后重定向到前一页 if($model->validate()) $this->redirect(Yii::app()->user->returnUrl); //重定向到之前需要身份验证的页面URL } // 显示登录表单 $this->render('login',array('model'=>$model)); }如上所示,我们首先创建了一个 LoginForm 模型示例;如果请求是一个 POST 请求(意味着这个登录表单被提交了),我们则使用提交的数据$_POST['LoginForm'] 填充 $model;然后我们验证此输入,如果验证成功,重定向用户浏览器到之前需要身份验证的页面。如果验证失败,或者此动作被初次访问,我们则渲染 login视图,此视图的内容将在后续章节中讲解。 提示: 在 login 动作中,我们使用Yii::app()->user->returnUrl 获取之前需要身份验证的页面URL。 组件Yii::app()->user 是一种 CWebUser (或其子类) ,它表示用户会话信息(例如用户名,状态)。 (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
