YII model模型和登陆详解
模型是 CModel 或其子类的实例。模型用于保持数据以及与其相关的业务逻辑。
模型是单独的数据对象。它可以是数据表中的一行,或者一个用户输入的表单。 数据对象的每个字段对应模型中的一个属性。每个属性有一个标签(label), 并且可以通过一系列规则进行验证。
Yii 实现了两种类型的模型:表单模型和 Active Record。二者均继承于相同的基类 CModel。
表单模型是 CFormModel 的实例。表单模型用于保持从用户的输入获取的数据。 这些数据经常被获取,使用,然后丢弃。例如,在一个登录页面中, 我们可以使用表单模型用于表示由最终用户提供的用户名和密码信息。更多详情,请参考 使用表单。
Active Record (AR) 是一种用于通过面向对象的风格抽象化数据库访问的设计模式。 每个 AR 对象是一个CActiveRecord 或其子类的实例。代表数据表中的一行。 行中的字段对应 AR 对象中的属性。更多关于 AR 的细节请阅读 Active Record.
CFormModel:代表收集HTML表单输入的数据模型。
class LoginForm extends CFormModel {}
表单的模型要继承CFormModel
controller
$model=new LoginForm;
$this->render('login',array('model'=>$model));
controller 实例化要用到的表单,传递给views
views
<?php $form=$this->beginWidget('CActiveForm', array('id'=>'login-form','enableAjaxValidation'=>true,)); ?>
....
<?php $this->endWidget(); ?>
views用 beginWidget('CActiveForm')生成一个表单
<?php
class LoginForm2 extends CFormModel
{
public $username;
public $password; public function rules()
{
return array(
array('username,password','required'),
array('password','authenticate'),
);
}
public function attributeLabels()
{
return array("username"=>"用户名",'password'=>"密码");
} public function authenticate($attribute,$params)
{
if($this->username=="admin")
$this->addError("username", "can't login with admin"); } }
或者:
public function authenticate($attribute,$params)
{
$this->_identity=new UserIdentity($this->username,$this->password);
if(!$this->_identity->authenticate())
$this->addError('password','Incorrect username or password.');
}
public array rules ()
{return}
array 要调用 validate() 时应用的有效性规则。
array('attribute list', 'validator name', 'on'=>'scenario name', ...validation parameters...)
attribute list: 指定属性 (以逗号分隔) 进行验证 ;
validator name: 指定要使用的验证程序。 它可以是方法的一个模型类的一个内置的验证器或验证程序类 (或其路径的别名) 名称的名称。 一种验证方法必须具有以下签名:
// $params refers to validation parameters given in the rulefunction validatorName($attribute,$params)
内置的验证程序是指在 CValidator::builtInValidators 中声明的验证程序之一。 验证程序的类是扩展 CValidator 的类。
on: 应执行有效性规则时,此选项指定的情形。 用逗号分开不同的方案。 如果未设置此选项,将在任何情况下应用规则。 请 方案 中有关此选项的更多详细信息,参阅。
附加参数用于初始化相应的验证程序属性。 请参阅 individal 验证器类 API 可能的属性。
我们的模型类非常简单,只有username和passsword两个属性。username的校验规则是不为空,且不能是“admin”,而password的校验规则只是不为空。注意,当我们检查到用户输入的username的值为“admin”时候,校验失败,我们添加错误信息为“can
not login with admin”,这段信息会在页面中的Yii提供的error元素中输出。
我们可以在rules方法中指定任何一条验证规则的错误信息,我们需要使用message属性。例如:array(‘username’, ‘required’,'message’=>’not
null’),当‘username’的内容为空的时候,我们会使用message指定的内容在页面上显示错误信息。当然我们可以使用中文,如果出现乱码,可以这样设置:array(‘username’,
‘required’,'message’=>iconv(“gb2312″,”utf-8″,”不能为空“))
你将main.php里的app配置加上language=>’zh_cn’,系统默认的提示就是中文的了!
其他验证规则案例:
array(‘title, content,
status’, ‘required’),
array(‘title’, ‘length’,
‘max’=>128),
array(‘status’, ‘in’,
‘range’=>array(0, 1, 2)),
array(‘tags’, ‘match’,
‘pattern’=>’/^[\w\s,]+$/’,'message’=>’Tags can only contain word
characters.’),
我们的页面代码如下:
<div class="form">
<?php
$form=$this->beginWidget('CActiveForm',array(
'id'=>'login-form',
'enableAjaxValidation'=>true,
'action'=>array('login2/login'),
));
?> <div class="row">
<?php echo $form->labelEx($model,'username');?>
<?php echo $form->textField($model,'username');?>
<?php echo $form->error($model,'username');?>
</div> <div class="row">
<?php echo $form->labelEx($model,'password');?>
<?php echo $form->passwordField($model,'password');?>
<?php echo $form->error($model,'password');?>
</div> <div class="row submit">
<?php echo CHtml::submitButton("登陆");?>
</div> <?php $this->endWidget();?>
</div>
对于每一个模型属性的页面表示来说,我们都会有一个Label来说明其属性名,还有一个input框用来输入该属性值,最后有个error元素来显示校验失败时的错误信息。Yii对Form及其子元素封装的太多,我们将以上php代码翻译成静态页面为:
<div class="form">
<form id="login-form" action="/validator/index.php?r=site/login" method="post">
<div class="row">
<label for="LoginForm_username" class="required">Username
<span class="required">*</span></label>
<input name="LoginForm[username]" id="LoginForm_username" type="text" value="" />
<div id="LoginForm_username_em_" class="errorMessage" style="display:none"></div>
</div>
<div class="row">
<label for="LoginForm_password" class="required">Password
<span class="required">*</span></label>
<input name="LoginForm[password]" id="LoginForm_password" type="password" value="" />
<div id="LoginForm_password_em_" class="errorMessage" style="display:none"></div>
</div>
<div class="row submit">
<input type="submit" name="yt0" value="Login" />
</div>
</form>
</div>
CActiveForm很重要的一个特性就是它支持Ajax校验。我们可以设置CActiveForm的enableAjaxValidation属性为ture来启动Ajax校验。例如,当用户在input框中输入一些值后就会触发Ajax校验。CActiveForm会向服务器提交Ajax请求,用来校验用户当前输入的值。服务器的校验一般是调用模型类Model的validate()方法。如果校验失败,相对应的错误信息将会被返回并显示给用户。即使用户在浏览器禁用javascript,他也会通过整个页面的提交自动回滚到传统的页面验证。
在客户端,Yii认为input框可以存在四个状态:初始化,校验,错误和成功。为了区分这些状态,CActiveForm自动指定了不同的CSS样式给包含此input框的HTML
element。默认情况下,这些CSS样式类的名字为:validating,error,success。当然我们可以使用CActiveForm的options属性去自定义他们。
CActiveForm的提交和校验是基于Ajax模式的。如果你的Form表单中有很大量的数据需要提交,那么这种Ajax模式的提交可能就不那么好了。这种情况下,你可以设计自己轻量级的Ajax校验。使用Yii对JQuery的支持?
使用CActiveForm来做Ajax校验,我们需要使用两个JS库:jquery.js和jquery.yiiactiveform.js。他们的位置在工程根目录下:assets\5ce53e17\文件夹中。不用担心,这些JS库Yii会自动发布到你的工程中。虽然这些动作Yii会悄悄的做,当你必须知道。
Yii的Ajax的校验效果是通过CSS来实现的,上文提到一个input框可以存在四个状态:初始化,校验,错误和成功。每个状态对应不同CSS样式类。初始化和校验这两个状态我们不需要关心,我们只注重用户校验失败和成功时,该input框的CSS样式。此外当校验失败的时候,我们还要定义错误信息的样式,从翻译过来的静态文本来来,我们需要定义errorMessage类。以下是我的CSS类:
/*标签是否换行*/
.form label {
font-size:12px; display:block; }
/*属性是否必填项,客户端根据model的rule方法而定*/
.form span.required {
color:red; }
/*校验出错时标签CSS样式*/
.form .error label {
color:#FFCC33; }
/*校验出错时输入框的CSS样式*/
.form .error input {
background:#FEE; border-color:#C00; }
/*校验出错时错误信息的CSS样式,我们可以设置其display属性让其不换行。*/
.form .errorMessage {
display:inline; color:red; font-size:12px; }
/*校验成功时标签CSS样式*/
.form .success label {
color:#000000; }
/*校验成功时输入框的CSS样式*/
.form .success input {
background:#E6EFC2; border-color:#C6D880; }
以上的CSS注释已经很详细了,我们来看看校验流程,首先我们需要先渲染我们的页面:
$model = new LoginForm;
$this->render(‘index’,array(‘model’=>$model));
注意,这里我们必须使用render()方法对其进行渲染。
我们的actionLogin如下:
<?php
class Login2Controller extends Controller
{
public function actionLogin()
{
$model=new LoginForm2();
//ajax validate
if(isset($_POST['ajax'])&& $_POST['ajax']==='login-form')
{
echo CActiveForm::validate($model);
Yii::app()->end(); }
//submit handle and validate
if(isset($_POST['LoginForm2']))
{
$model->attributes=$_POST['LoginForm2'];
if($model->validate())
{
//no business login handel
$this->renderPartial("success");
Yii::app()->end();
}
} $this->render("login",array('model'=>$model));
} }
当input框失去焦点的时候,页面会向服务器提交Ajax请求,服务器端就会根据模型类LoginForm中定义的校验规则就其就行验证。如果校验成功,则input框会按指定的success样式类去显示,如果校验失败,则input框会按指定的error样式类去显示,同时还会按照errorMessage指定的样式类显示错误信息。
需要注意的是,如果我们对用户输入的信息进行了校验,而且有可能校验失败,但是用户在校验失败的情况下,仍然可以提交Form表单。所以当用户提交Form表单的处理代码中,我们仍需要对用户的输入进行校验。
到这里controller,model和view就写完了。
CActiveForm其他组件的使用
1. textArea
这个组件没有太多讲的,主要注意行列的属性配置,使用代码:
<?php echo
$form->textArea($model,’textArea’,array(‘rows’=>10,’cols’=>50)); ?>
2. fileField
虽然Yii封装了这个组件,但是它并没有做更多的支持,它的上传需要更多的配置,它也不支持Ajax校验。使用代码:
<?php echo $form->fileField($model,’fileField’);
?>
3. radioButtonList
这是一个radio集合组件。使用代码:
<?php echo
$form->radioButtonList($model,’radioButtonList’,
array(’1′=>’Male’,’0′=>’Female’),
array(‘separator’=>’ ’,'labelOptions’=>array(‘class’=>’radiolabel’))
)?>
Yii框架封装的元素集合组件大致为4个参数:
$model,$property,$data,$htmlOptios
前面两个参数是我们关联模型类和指定的属性。第三个参数是一个数组,他是元素集合组件的数据来源,上面的代码中配置了两个数组元素,则会对应生成两个radio,radio的值为1或者0,radio的标签为Male或者Female。Yii默认将两个radio之间使用<br/>间隔,即两个radio不在同一行上,我们可以使用separator属性更改其间隔方式,这里我们使用空格符来间隔两个radio,这样他们显示在同一行上。另外在同一个radio中,其标签和实体也是换行的,原因在于标签<label>会换行,我们可以给label标签添加CSS样式,改变其display值为inline将其与radio实体排列在一行。
radioButtonList对应模型类中的属性值不是数组,只是一个单一数值或者字符而已,虽然他是一个集合组件,但是他是单选的,所以最终只有一个单一值提交服务器端。
另外值得注意的是,Yii封装的这些组件的初始值不能够在标签中设置,Yii自动会从模型类中读取属性值,然后在组件上显示出来。所以,如果你想在页面渲染前初始化一些组件的默认值,那么你可以直接初始化模型类就可以了。
4. checkBoxList
这是一个checkBox集合组件,使用代码:
<?php echo $form->checkBoxList($model,’checkBoxList’, array(’1′=>’Football’,’2′=>’Music’,’3′=>’Game’,’4′=>’basketball’), array(‘separator’=>’ ’,'labelOptions’=>array(‘class’=>’checkboxlabel’)) )?>
这个组件同上,唯一不同的是这个组件是多选的,所以他对应的模型类的属性应该是一个数组。这个组件将你选中的每个checkBox的值构造成一个数组提交服务器端。例如我们选中了Football和Game,那个该组件构造的数组将是array(‘1’,’3’),没有选中的checkBox不会被构造进这个数组中。反之从服务器段读取数组,然后显示该组件也是同样的道理。
5. listBox
本质上它是一个select,但是它会显示所有的option。使用代码如下:
<?php echo $form->listBox($model,’listBox’, array(’1′=>’Football’,’2′=>’Music’,’3′=>’Game’,’4′=>’basketball’), array(‘size’=>8,’multiple’=>false,’class’=>’listbox’) )?>
需要说明的属性‘size’表示该select的大小,虽然我只定义了4个option,但是我仍然想让它占据8个option的高度。属性multiple为是否多选。属性class为select的CSS样式类,但是貌似不起作用。在需要说明的一点是,虽然它可以单选和多选,但是他对应的模型类的属性始终是一个数组。
6. dropDownList
本质上它是一个真正意义上select,因为他不会显示所有的option,使用代码如下:
1 <?php
2
3 $models =
4 person::model()->findAll(array(‘order’=>’age’));
5
6 $list = CHtml::listData($models,’id’,'username’);
7
8 echo $form->dropDownList($model,’dropDownList’,$list,array(‘empty’=>’Select
9 a user’)
10
11 )?>
这个组件的使用跟select差不多,对应模型层的属性是一个单一数值或者字符,而不是数组。属性empty指定了select的第一个option,相当于初始化值。
这里我们需要说明的是以上这些集合组件的数据来源。本质上其实我们就是查询数据库,将结果集封装成一个数组,其实查询数据结果集本来就是一个数组。这里我们使用AR类person按年龄查询所有的记录,然后使用CHtml的listData方法将查询记录中的id字段和username字段构造成一个简单的数组$list,然后我们只需要在dropDownList的标签配置中应用即可。
最后我们介绍一下服务器端获取页面数据,因为我们已经将模型类和我们的页面标签相关联,所以使用标签显示模型类属性或者从显示标签中获取模型类属性是十分简单的。在服务器端我们获取页面数据的时候,可以使用如下代码:
$model = new Form; $model->attributes = $_POST['Form'];
以上代码会将用户提交的数据自动填充到模型类的属性中,这个方式称为安全特性分配。首先我们的页面中必须已经将标签和模型类Form关联。需要注意的是$_POST的参数就是模型类的名称Form,而不是标签名称。最重要的问题在于我们模型类中的属性必须是安全的,否则我们的安全特性分配将会失败。指定模型类中的属性为安全的是通过实现模型类中的
Rules方法,即校验规则方法。我们可以直接将模型类的指定属性指定为”safe”或者指定其他校验规则,因为Yii因为如果一个属性通过某个校验后它就可以被认为是安全的了。
public function rules() { return array( array(‘property’,'safe’) ); }
参考:http://studyjphp.blog.163.com/blog/static/1312612192012495914186/
http://www.cnblogs.com/partoo/archive/2012/04/10/2491126.html
更多:http://blog.csdn.net/renzhenhuai/article/details/15813997
http://hi.baidu.com/lvzhaocun/item/9097234f5a3319f2dd0f6c13
yii自定义登陆错误信息:
http://www.yiiframework.com/wiki/463/custom-login-error-messages/
YII model模型和登陆详解的更多相关文章
- 基于模型的特征选择详解 (Embedded & Wrapper)
目录 基于模型的特征选择详解 (Embedded & Wrapper) 1. 线性模型和正则化(Embedded方式) 2. 基于树模型的特征选择(Embedded方式) 3. 顶层特征选择算 ...
- CSS3盒模型display:box详解
display:box;box-flex是css3新添加的盒子模型属性,它的出现可以解决我们通过N多结构.css实现的布局方式.经典的一个布局应用就是布局的垂直等高.水平均分.按比例划分. 目前box ...
- Kaggle网站流量预测任务第一名解决方案:从模型到代码详解时序预测
Kaggle网站流量预测任务第一名解决方案:从模型到代码详解时序预测 2017年12月13日 17:39:11 机器之心V 阅读数:5931 近日,Artur Suilin 等人发布了 Kaggl ...
- Java内存模型相关原则详解
在<Java内存模型(JMM)详解>一文中我们已经讲到了Java内存模型的基本结构以及相关操作和规则.而Java内存模型又是围绕着在并发过程中如何处理原子性.可见性以及有序性这三个特征来构 ...
- 不止面试02-JVM内存模型面试题详解
第一部分:面试题 本篇文章我们将尝试回答以下问题: 描述一下jvm的内存结构 描述一下jvm的内存模型 谈一下你对常量池的理解 什么情况下会发生栈内存溢出?和内存溢出有什么不同? String str ...
- DJango模型Meta选项详解
Django模型之Meta选项详解 MEAT选项 Django模型类的Meta是一个内部类,它用于定义一些Django模型类的行为特性.而可用的选项大致包含以下几类 abstract 这个属性是定义当 ...
- OSI模型各层详解
1. OSI概述 1.1 模拟器说明 1.1.1 模拟器的作用 搭建实验环境进行测试. 1.1.2 模拟器的类型 PT:一般是学校中使用,命令不完整,且不能抓包 GNS3:思科(CCNA,CCNP), ...
- yii 核心类classes.php详解(持续更新中...)
classes.php在yii运行的时候将被自动加载,位于yii2文件夹底下. <?php /** * Yii core class map. * * This file is automati ...
- Yii 框架里数据库操作详解-[增加、查询、更新、删除的方法 'AR模式']
public function getMinLimit () { $sql = "..."; $result = yii::app()->db-& ...
随机推荐
- RedHat搭建IPA-Server
ipa-server是红帽身份验证的一个完整解决方案,上游的开源项目是freeIPA,它本身不提供具体功能,而是整合了389-ds.ipa-server-dns.krb5-server等核心软件包,形 ...
- 微信45028错误,微信has no masssend quota hint错误
微信45028,微信has no masssend quota hint 微信测试账号群发出现45028,has no masssend quota hint错误 >>>>&g ...
- AES加解密【示例】
代码 /** * AES算法加密.JRE默认只能用16个字节(128)位密钥 */ public class AESUtils { //使用指定转换的 Cipher 对象 publ ...
- Modem常用概念
真实设备的标识,即DEVICE_ID.比如,Android设备是手机,这个DEVICE_ID可以同通过TelephonyManager.getDeviceId()获取,它根据不同的手机设备返回IMEI ...
- 隐藏元素的宽高无法通过原生js获取的问题
1.起源:移动app项目中,页面加载时需要加载国家下拉列表,将隐藏的透明浮层和一个显示加载过程中的框 显示出来,隐藏的透明浮层设置宽高都是100%即可,而这个加载提示框需要先得出它的宽高,然后再根据页 ...
- 【原创教程】JavaScript详解之语法和对象
JavaScript的好的想法:函数.弱类型.动态对象和一个富有表现力的对象字面量表示法. JavaScript的坏的想法:基于全局变量的编程模型. 好了,不管他是好的还是坏的,都是我的最爱,下面 ...
- Java-Android 之页面的跳转和结构的搭建
Android中每个页面就是一个Activity,要合理的让这些页面实现跳转,才是关键,这里讲一个最简单的 首先,有一个主页面main.xml <?xml version="1.0&q ...
- MES项目中出现的一个事务嵌套的使用场景
昨天在MES项目中,需要在业务逻辑的几个关键点记录错误信息,需要把错误信息写入数据表. 但是由于整个业务逻辑都是包在一个事务模板里面的 比如这样的: WhhTransactionTemplate tr ...
- C# 实现的多线程异步Socket数据包接收器框架
转载自Csdn : http://blog.csdn.net/jubao_liang/article/details/4005438 几天前在博问中看到一个C# Socket问题,就想到笔者2004年 ...
- Android- Context理解
学习了安卓以后还是不理解Context的用法:Api文档链接http://wear.techbrood.com/reference/android/content/Context.html 一个非常好 ...