首頁 後端開發 php教程 Yii中表單用法實例

Yii中表單用法實例

Jun 15, 2018 am 11:47 AM
yii 表單

這篇文章主要介紹了Yii中表單用法,結合實例形式較為詳細的分析總結了Yii針對表單的各種常用操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下

本文實例講述了Yii中表單用法。分享給大家供大家參考,具體如下:

在 Yii 中處理表單時,通常需要以下步驟:

1. 建立用於表現所要收集資料欄位的模型類別。
2. 建立一個控制器動作,回應表單提交。
3. 在檢視腳本中建立與控制器動作相關的表單。

一、建立模型

在編寫表單所需的HTML 程式碼之前,我們應該先確定來自最終使用者輸入的資料的類型,以及這些資料應符合什麼樣的規則。模型類別可用於記錄這些資訊。如模型章節所定義的,模型是保存使用者輸入和驗證這些輸入的中心位置。

取決於使用使用者輸入資料的方式,我們可以建立兩種類型的模型。如果使用者輸入被收集、使用然後丟棄,我們應該建立一個表單模型;

如果使用者的輸入被收集後要儲存到資料庫,我們應該使用一個Active Record。兩種類型的模型共用相同的基底類別 CModel,它定義了表單所需的通用介面。

1、定義模型類別

例如建立為表單模型:

class LoginForm extends CFormModel
{
public $username;
public $password;
public $rememberMe=false;
}
登入後複製

LoginForm中定義了三個屬性: $username, $password 和$rememberMe。他們用於保存用戶輸入的用戶名和密碼,以及用戶是否想記住他的登入的選項。由於 $rememberMe 有一個預設的值false,對應的選項在初始化顯示在登入表單中時將是未勾選狀態。

我們將這些成員變數稱為特性(attributes)而不是屬性(properties),以區別於普通的屬性(properties)。特性(attribute)是一個主要用於儲存來自使用者輸入或資料庫資料的屬性(propertiy)。

2、聲明驗證規則

一旦使用者提交了他的輸入,模型被填充,我們就需要在使用前確保使用者的輸入是有效的。這是透過將使用者的輸入和一系列規則執行驗證來實現的。我們在 rules() 方法中指定這些驗證規則,此方法應傳回一個規則配置陣列。

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','错误的用户名或密码。');
}
}
登入後複製

rules() 傳回的每個規則必須是以下格式:

array('AttributeList', 'Validator', 'on'=>'ScenarioList', ...附加选项)
登入後複製

其中:

AttributeList(特性清單)是需要透過此規則驗證的特性清單字串,每個特性名字由逗號分隔;
Validator(驗證器) 指定要執行驗證的種類;
on 參數是可選的,它指定此規則應被套用到的場景清單;

附加選項是一個名值對數組,用於初始化對應驗證器的屬性值。

有三種方式可在驗證規則中指定 Validator:

第一, Validator 可以是模型類別中一個方法的名字,就像上面範例中的 authenticate 。驗證方法必須是下面的結構:

public function 验证器名称($attribute,$params) { ... }
登入後複製

第二,Validator可以是驗證器類別的名字,當此規則被應用時,一個驗證器類別的實例將被建立以執行實際驗證。規則中的附加選項用於初始化實例的屬性值。驗證器類別必須繼承自 CValidator。

第三,Validator 可以是一個預先定義的驗證器類別的別名。在上面的範例中,required 名字是 CRequiredValidator 的別名,它用來確保所驗證的特性值不為空。以下是預先定義的驗證器別名的完整清單:

boolean: CBool​​eanValidator 的別名,確保特性有一個 CBool​​eanValidator::trueva lue 或 CBool​​eanValidator::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。

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

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

3、安全的特性赋值

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

$model=new LoginForm;
if(isset($_POST['LoginForm']))
$model->attributes=$_POST['LoginForm'];
登入後複製

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

foreach($_POST['LoginForm'] as $name=>$value)
{
if($name 是一个安全的特性)
$model->$name=$value;
}
登入後複製

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

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

array('username, password', 'required', 'on'=>'login, register'),
array('email', 'required', 'on'=>'register'),
登入後複製

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

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

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

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

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

array('content', 'safe')
登入後複製

还有一个用于声明一个属性为不安全的 unsafe 规则:

array('permission', 'unsafe')
登入後複製

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

4、触发验证

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

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

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

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

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

public function rules()
{
return array(
array('username, password', 'required'),
array('password_repeat', 'required', 'on'=>'register'),
array('password', 'compare', 'on'=>'register'),
);
}
登入後複製

第一个规则将应用于所有场景,而第二个将只会应用于 register 场景。

5、提取验证错误

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

6、特性标签

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

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

二、创建动作

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

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));
}
登入後複製

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

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

让我们特别留意一下 login 动作中出现的下面的 PHP 语句:

$model->attributes=$_POST['LoginForm'];
登入後複製

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

$model->username=$_POST['LoginForm']['username'];
$model->password=$_POST['LoginForm']['password'];
$model->rememberMe=$_POST['LoginForm']['rememberMe'];
登入後複製

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

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

三、创建表单

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

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

CHtml::textField($name,$value,array('submit'=>''));
登入後複製

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

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

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

beginWidget('CActiveForm'); ?>
errorSummary($model); ?>
label($model,'username'); ?>
textField($model,'username') ?>
label($model,'password'); ?>
passwordField($model,'password') ?>
checkBox($model,'rememberMe'); ?>
label($model,'rememberMe'); ?>
endWidget(); ?>
登入後複製

四、收集表格输入

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

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

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));
}
登入後複製

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

NamePriceCount
Description
$item): ?>
登入後複製

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

如何通过Yii统计不同类型邮箱数量

Yii和CKEditor实现图片上传的功能

Yii2如何使用Bootbox外掛實現自訂彈窗

###################################################################

以上是Yii中表單用法實例的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何實現PHP表單提交後的頁面跳轉 如何實現PHP表單提交後的頁面跳轉 Aug 12, 2023 am 11:30 AM

如何實現PHP表單提交後的頁面跳轉【簡介】在Web開發中,表單的提交是一項常見的功能需求。當使用者填寫完表單並點擊提交按鈕後,通常需要將表單資料傳送至伺服器進行處理,並在處理完後將使用者重新導向至另一個頁面。本文將介紹如何使用PHP來實現表單提交後的頁面跳躍。 【步驟一:HTML表單】首先,我們需要在HTML頁面中撰寫一個包含表單的頁面,以便使用者填寫需要提交的資料。

如何使用 JavaScript 實作表單的輸入框內容自動提示功能? 如何使用 JavaScript 實作表單的輸入框內容自動提示功能? Oct 20, 2023 pm 04:01 PM

如何使用JavaScript實作表單的輸入框內容自動提示功能?簡介:表單的輸入框內容自動提示功能在網頁應用程式中非常常見,它可以幫助使用者快速輸入正確的內容。本文將介紹如何使用JavaScript實作此功能,並提供具體的程式碼範例。在建立HTML結構首先,我們需要建立一個包含輸入框和自動提示清單的HTML結構。可以使用以下程式碼:<!DOCTYP

如何處理PHP表單中的使用者權限管理 如何處理PHP表單中的使用者權限管理 Aug 10, 2023 pm 01:06 PM

如何處理PHP表單中的使用者權限管理隨著Web應用程式的不斷發展,使用者權限管理是重要的功能之一。使用者權限管理可以控制使用者在應用程式中的操作權限,確保資料的安全性和合法性。在PHP表單中,使用者權限管理可以透過一些簡單的程式碼來實現。本文將介紹如何處理PHP表單中的使用者權限管理,並給予對應的程式碼範例。一、使用者角色的定義與管理首先,將使用者角色定義與管理是使用者權

如何使用 JavaScript 實作表單的輸入框內容即時校驗功能? 如何使用 JavaScript 實作表單的輸入框內容即時校驗功能? Oct 18, 2023 am 08:47 AM

如何使用JavaScript實作表單的輸入框內容即時校驗功能?在許多網頁應用程式中,表單是使用者與系統之間最常用的互動方式。然而,使用者輸入的內容往往需要進行有效性校驗,以確保資料的準確性和完整性。在這篇文章中,我們將學習如何使用JavaScript實作表單的輸入框內容即時校驗功能,並提供具體的程式碼範例。在建立表單首先,我們需要在HTML中建立一個簡單的表

如何使用HTML、CSS和jQuery實現表單自動保存的進階功能 如何使用HTML、CSS和jQuery實現表單自動保存的進階功能 Oct 28, 2023 am 08:20 AM

如何使用HTML、CSS和jQuery實現表單自動保存的高級功能在現代網頁應用中,表單是非常常見的元素之一。當使用者在輸入表單資料時,如何能夠實現自動儲存的功能,不僅可以提高使用者的使用體驗,也能確保資料的安全性。本文將介紹如何使用HTML、CSS和jQuery來實作表單的自動儲存功能,並附上具體的程式碼範例。一、HTML表單的結構建構我們先來建立一個簡單的HT

PHP表單處理:表單資料查詢與篩選 PHP表單處理:表單資料查詢與篩選 Aug 07, 2023 pm 06:17 PM

PHP表單處理:表單資料查詢與篩選引言在網路開發中,表單是一種重要的互動方式,使用者可以透過表單向伺服器提交資料並進行進一步的處理。本文將介紹如何使用PHP處理表單資料的查詢與篩選功能。表單的設計與提交首先,我們需要設計一個包含查詢與篩選功能的表單。常見的表單元素包括輸入框、下拉清單、單選框、複選框等,根據具體需求進行設計。用戶在提交表單時,會將資料以POS

Laravel表單類別使用技巧:提高效率的方法 Laravel表單類別使用技巧:提高效率的方法 Mar 11, 2024 pm 12:51 PM

在編寫網站或應用程式時,表單是不可或缺的一部分。 Laravel作為一個流行的PHP框架,提供了豐富而強大的表單類,使得表單處理變得更加簡單和高效。本文將介紹一些Laravel表單類別的使用技巧,幫助你提升開發效率。下面透過具體的程式碼範例來詳細講解。建立表單要在Laravel中建立表單,首先需要在檢視中編寫對應的HTML表單。在處理表單時,可以使用Laravel

Symfony vs Yii2:哪個框架比較適合開發大型Web應用? Symfony vs Yii2:哪個框架比較適合開發大型Web應用? Jun 19, 2023 am 10:57 AM

隨著Web應用需求的不斷增長,開發者在選擇開發框架方面也越來越有選擇的空間。 Symfony和Yii2是兩個備受歡迎的PHP框架,它們都具有強大的功能和效能,但在面對需要開發大型網路應用程式時,哪個框架更適合呢?接下來我們將對Symphony和Yii2進行比較分析,以幫助你更好地進行選擇。基本概述Symphony是一個由PHP編寫的開源Web應用框架,它是建立

See all articles