加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

Yii中表单用法实例详解

发布时间:2020-12-13 03:04:01 所属栏目:PHP教程 来源:网络整理
导读:《PHP实战:Yii中表单用法实例详解》要点: 本文介绍了PHP实战:Yii中表单用法实例详解,希望对您有用。如果有疑问,可以联系我们。 PHP实战 本篇章节讲解Yii中表单用法.供大家参考研究,具体如下: PHP实战 在 Yii 中处理表单时,通常需要以下步骤:

《PHP实战:Yii中表单用法实例详解》要点:
本文介绍了PHP实战:Yii中表单用法实例详解,希望对您有用。如果有疑问,可以联系我们。

PHP实战本篇章节讲解Yii中表单用法.分享给大家供大家参考,具体如下:

PHP实战在 Yii 中处理表单时,通常需要以下步骤:

PHP实战1. 创建用于表现所要收集数据字段的模型类.
2. 创建一个控制器动作,响应表单提交.
3. 在视图脚本中创建与控制器动作相关的表单.

PHP实战一、创建模型

PHP实战在编写表单所需的 HTML 代码之前,我们应该先确定来自最终用户输入的数据的类型,以及这些数据应符合什么样的规则.模型类可用于记录这些信息.正如模型章节所定义的,模型是保存用户输入和验证这些输入的中心位置.

PHP实战取决于使用用户所输入数据的方式,我们可以创建两种类型的模型.如果用户输入被收集、使用然后丢弃,我们应该创建一个表单模型;

PHP实战如果用户的输入被收集后要保存到数据库,我们应使用一个Active Record.两种类型的模型共享同样的基类 CModel,它定义了表单所需的通用接口.

PHP实战1、定义模型类

PHP实战例如创建为一个表单模型:

PHP实战
class LoginForm extends CFormModel
{
public $username;
public $password;
public $rememberMe=false;
}

PHP实战LoginForm中定义了三个属性: $username,$password 和$rememberMe.他们用于保存用户输入的用户名和暗码,还有用户是否想记住他的登录的选项.由于 $rememberMe 有一个默认的值false,相应的选项在初始化显示在登录表单中时将是未勾选状态.

PHP实战我们将这些成员变量称为特性(attributes)而不是属性(properties),以区别于普通的属性(properties).特性(attribute)是一个主要用于存储来自用户输入或数据库数据的属性(propertiy).

PHP实战2、声明验证规则

PHP实战一旦用户提交了他的输入,模型被填充,我们就需要在使用前确保用户的输入是有效的.这是通过将用户的输入和一系列规则执行验证实现的.我们在 rules() 办法中指定这些验证规则,此办法应返回一个规则配置数组.

PHP实战
class LoginForm extends CFormModel
{
public $username;
public $password;
public $rememberMe=false;
private $_identity;
public function rules()
{
return array(
array('username,password','required'),//username 和 password 为必填项
array('rememberMe','boolean'),//rememberMe 应该是一个布尔值
array('password','authenticate'),//password 应被验证(authenticated)
);
}
public function authenticate($attribute,$params)
{
$this->_identity=new UserIdentity($this->username,$this->password);
if(!$this->_identity->authenticate())
$this->addError('password','错误的用户名或暗码.');
}
}

PHP实战rules() 返回的每个规则必须是以下格式:

代码如下:
array('AttributeList','Validator','on'=>'ScenarioList',...附加选项)

其中:

PHP实战AttributeList(特性列表)是需要通过此规则验证的特性列表字符串,每个特性名字由逗号分隔;
Validator(验证器) 指定要执行验证的种类;
on 参数是可选的,它指定此规则应被应用到的场景列表;

PHP实战附加选项 是一个名值对数组,用于初始化相应验证器的属性值.

PHP实战有三种方式可在验证规则中指定 Validator:

PHP实战第一,Validator 可以是模型类中一个办法的名字,就像上面示例中的 authenticate .验证办法必须是下面的结构:

代码如下:
public function 验证器名称($attribute,$params) { ... }

第二,Validator可以是一个验证器类的名字,当此规则被应用时,一个验证器类的实例将被创建以执行实际验证.规则中的附加选项用于初始化实例的属性值.验证器类必须继承自 CValidator.

PHP实战第三,Validator 可以是一个预定义的验证器类的别名.在上面的例子中,required 名字是 CRequiredValidator 的别名,它用于确保所验证的特性值不为空.下面是预定义的验证器别名的完整列表:

PHP实战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.

PHP实战下面我们列出了几个只用这些预定义验证器的示例:

PHP实战
// 用户名为必填项
array('username',// 用户名必须在 3 到 12 个字符之间
array('username','length','min'=>3,'max'=>12),// 在注册场景中,密码password必须和password2一致.
array('password','compare','compareAttribute'=>'password2','on'=>'register'),// 在登录场景中,密码必须接受验证.
array('password','authenticate','on'=>'login'),

PHP实战3、平安的特性赋值

PHP实战在一个类的实例被创建后,我们通常需要用最终用户提交的数据填充它的特性.这可以通过如下块赋值(massive assignment)方式轻松实现:

PHP实战
$model=new LoginForm;
if(isset($_POST['LoginForm']))
$model->attributes=$_POST['LoginForm'];

PHP实战最后的表达式被称作 块赋值(massive assignment),它将 $_POST['LoginForm'] 中的每一项复制到相应的模型特性中.这相当于如下赋值办法:

PHP实战
foreach($_POST['LoginForm'] as $name=>$value)
{
if($name 是一个平安的特性)
$model->$name=$value;
}

PHP实战检测特性的平安非常重要,例如,如果我们以为一个表的主键是平安的而暴露了它,那么攻击者可能就获得了一个修改记录的主键的机会,从而篡改未授权给他的内容.

PHP实战特性如果出现在相应场景的一个验证规则中,即被认为是平安的.例如:

PHP实战
array('username,'required','on'=>'login,register'),array('email',

PHP实战如上所示,username 和 password 特性在 login 场景中是必填项.而 username,password 和 email特性在 register 场景中是必填项.于是,如果我们在 login 场景中执行块赋值,就只有 username 和 password会被块赋值.因为只有它们出现在 login 的验证规则中.另一方面,如果场景是 register,这三个特性就都可以被块赋值.

PHP实战
// 在登录场景中
$model=new User('login');
if(isset($_POST['User']))
$model->attributes=$_POST['User'];
// 在注册场景中
$model=new User('register');
if(isset($_POST['User']))
$model->attributes=$_POST['User'];

PHP实战那么为什么我们使用这样一种策略来检测特性是否平安呢?背后的基本原理就是:如果一个特性已经有了一个或多个可检测有效性的验证规则,那我们还担心什么呢?

PHP实战请记住,验证规则是用于检查用户输入的数据,而不是检查我们在代码中生成的数据(例如时间戳,自动产生的主键).因此,不要为那些不接受最终用户输入的特性添加验证规则.

PHP实战有时候,我们想声明一个特性是平安的,即使我们没有为它指定任何规则.例如,一篇文章的内容可以接受用户的任何输入.我们可以使用特殊的 safe 规则实现此目的:

代码如下:
array('content','safe')

还有一个用于声明一个属性为不平安的 unsafe 规则:
代码如下:
array('permission','unsafe')

unsafe 规则并不常用,它是我们之前定义的平安特性的一个例外.

PHP实战4、触发验证

PHP实战一旦模型被用户提交的数据填充,我们就可以调用 CModel::validate() 触发数据验证进程.此办法返回一个指示验证是否成功的值.对CActiveRecord? 模型来说,验证也可以在我们调用其 CActiveRecord::save() 办法时自动触发.

PHP实战我们可以通过设置scenario属性来设置场景属性,这样,相应场景的验证规则就会被应用.

PHP实战验证是基于场景执行的. scenario属性指定了模型当前用于的场景和当前使用的验证规则集.例如,在 login 场景中,我们只想验证用户模型中的username 和 password 输入;而在 register 场景中,我们需要验证更多的输入,例如 email,address,等.下面的例子演示了如安在 register 场景中执行验证:

PHP实战
// 在注册场景中创建一个 User 模型.等价于:
// $model=new User;
// $model->scenario='register';
$model=new User('register'); //给模型类添加参数,该参数就是要触发的验证场景
// 将输入的值填充到模型
$model->attributes=$_POST['User'];
// 执行验证
if($model->validate())  // 如果输入有效
...
else
...

PHP实战规则关联的场景可以通过规则中的 on 选项指定.如果 on 选项未设置,则此规则会应用于所有场景.例如:

PHP实战
public function rules()
{
return array(
array('username,array('password_repeat',array('password',);
}

PHP实战第一个规则将应用于所有场景,而第二个将只会应用于 register 场景.

PHP实战5、提取验证错误

PHP实战验证完成后,任何可能产生的错误将被存储在模型对象中.我们可以通过调用 CModel::getErrors()和CModel::getError()? 提取这些错误信息.这两个办法的不同点在于第一个办法将返回所有 模型特性的错误信息,而第二个将只返回第一个 错误信息.

PHP实战6、特性标签

PHP实战当设计表单时,我们通常需要为每个表单域显示一个标签.标签告诉用户他应该在此表单域中填写什么样的信息.虽然我们可以在视图中硬编码一个标签,但如果我们在相应的模型中指定(标签),则会更加灵活方便.

PHP实战默认情况下 CModel 将简单的返回特性的名字作为其标签.这可以通过覆盖 attributeLabels() 办法自定义.正如在接下来的小节中我们将看到的,在模型中指定标签会使我们能够更快的创建出更强大的表单.

PHP实战二、创建动作

PHP实战有了模型,我们就可以开始编写用于操作此模型的逻辑了.我们将此逻辑放在一个控制器的动作中.对登录表单的例子来讲,相应的代码就是:

PHP实战
public function actionLogin()
{
$model=new LoginForm;
if(isset($_POST['LoginForm']))
{
// 收集用户输入的数据
$model->attributes=$_POST['LoginForm'];
// 验证用户输入,并在判断输入正确后重定向到前一页
if($model->validate())
$this->redirect(Yii::app()->user->returnUrl); //重定向到之前需要身份验证的页面URL
}
// 显示登录表单
$this->render('login',array('model'=>$model));
}

PHP实战如上所示,我们首先创建了一个 LoginForm 模型示例;如果哀求是一个 POST 哀求(意味着这个登录表单被提交了),我们则使用提交的数据$_POST['LoginForm'] 填充 $model;然后我们验证此输入,如果验证成功,重定向用户浏览器到之前需要身份验证的页面.如果验证失败,或者此动作被初次访问,我们则渲染 login视图,此视图的内容将在后续章节中讲解.

PHP实战提示: 在 login 动作中,我们使用Yii::app()->user->returnUrl? 获取之前需要身份验证的页面URL. 组件Yii::app()->user 是一种 CWebUser (或其子类),它表示用户会话信息(例如用户名,状态).

PHP实战让我们特别把稳一下 login 动作中出现的下面的 PHP 语句:

代码如下:
$model->attributes=$_POST['LoginForm'];

正如我们在 平安的特性赋值 中所讲的,这行代码使用用户提交的数据填充模型. attributes 属性由 CModel定义,它接受一个名值对数组并将其中的每个值赋给相应的模型特性.因此如果 $_POST['LoginForm']给了我们这样的一个数组,上面的那段代码也就等同于下面冗长的这段 (假设数组中存在所有所需的特性):
PHP实战
$model->username=$_POST['LoginForm']['username'];
$model->password=$_POST['LoginForm']['password'];
$model->rememberMe=$_POST['LoginForm']['rememberMe'];

PHP实战注意: 为了使 $_POST['LoginForm'] 传递给我们的是一个数组而不是字符串,我们需要在命名表单域时遵守一个规范.具体的,对应于模型类 C 中的特性 a 的表单域,我们将其命名为 C[a] .例如,我们可使用LoginForm[username] 命名 username 特性相应的表单域.

PHP实战现在剩下的工作就是创建 login 视图了,它应该包含一个带有所需输入项的 HTML 表单.

PHP实战三、创建表单

PHP实战编写 login 视图是很简单的,我们以一个 form 标记开始,它的 action 属性应该是前面讲述的 login动作的URL.然后我们需要为 LoginForm类中声明的属性插入标签和表单域.最后,我们插入一个可由用户点击提交此表单的提交按钮.所有这些都可以用纯HTML代码完成.

PHP实战Yii 提供了几个助手(helper)类简化视图编写.例如,要创建一个文本输入域,我们可以调用 CHtml::textField();要创建一个下拉列表,则调用 CHtml::dropDownList().
例如,如下代码将生成一个文本输入域,它可以在用户修改了其值时触颁发单提交动作.

代码如下:
CHtml::textField($name,$value,array('submit'=>''));

下面,我们使用 CHtml? 创建一个登录表单.我们假设变量 $model 是 LoginForm 的实例.

PHP实战上述代码生成了一个更加动态的表单,CHtml::activeLabel()生成一个与指定模型的特性相关的标签.如果此特性有一个输入错误,此标签的CSS class 将变为 error,通过 CSS样式改变了标签的外观.相似的,CHtml::activeTextField() 为指定模型的特性生成一个文本输入域,并会在错误发生时改变它的CSS class.

PHP实战我们还可以使用一个新的小物件 CActiveForm? 以简化表单创建.这个小物件可同时提供客户端及服务器端无缝的、一致的验证.使用 CActiveForm,上面的代码可重写为:

PHP实战
beginWidget('CActiveForm'); ?>
errorSummary($model); ?>
label($model,'username'); ?>
textField($model,'username') ?>
label($model,'password'); ?>
passwordField($model,'password') ?>
checkBox($model,'rememberMe'); ?>
label($model,'rememberMe'); ?>
endWidget(); ?>

PHP实战四、收集表格输入

PHP实战有时我们想通过批量模式收集用户输入.也就是说,用户可以为多个模型实例输入信息并将它们一次性提交.我们将此称为 表格输入(tabular input),因为这些输入项通常以 HTML 表格的形式呈现.

PHP实战要使用表格输入,我们首先需要创建或填充一个模型实例数组,取决于我们是想插入还是更新数据.然后我们从 $_POST变量中提取用户输入的数据并将其赋值到每个模型.和单模型输入稍有不同的一点就是:我们要使用 $_POST['ModelClass'][$i]提取输入的数据而不是使用 $_POST['ModelClass'].

PHP实战
public function actionBatchUpdate()
{
// 假设每一项(item)是一个 'Item' 类的实例,// 提取要通过批量模式更新的项
$items=$this->getItemsToUpdate();
if(isset($_POST['Item']))
{
$valid=true;
foreach($items as $i=>$item)
{
if(isset($_POST['Item'][$i]))
$item->attributes=$_POST['Item'][$i];
$valid=$valid && $item->validate();
}
if($valid) // 如果所有项目有效
// ...则在此处做一些操作
}
// 显示视图收集表格输入
$this->render('batchUpdate',array('items'=>$items));
}

PHP实战准备好了这个动作,我们需要继续 batchUpdate 视图的工作以在一个 HTML 表格中显示输入项.

PHP实战
NamePriceCount
Description
$item): ?>

PHP实战注意,在上面的代码中我们使用了 "[$i]name" 而不是 "name" 作为调用 CHtml::activeTextField 时的第二个参数.

PHP实战如果有任何验证错误,相应的输入项将会自动高亮显示,就像前面我们讲解的单模型输入一样.

PHP实战希望本文所述对大家基于Yii框架的PHP程序设计有所赞助.

编程之家培训学院每天发布《PHP实战:Yii中表单用法实例详解》等实战技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培养人才。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读