《PHP實戰:Yii中表單用法實例詳解》要點:
本文介紹了PHP實戰:Yii中表單用法實例詳解,希望對您有用。如果有疑問,可以聯系我們。
相關主題: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() 返回的每個規則必須是以下格式:
PHP實戰AttributeList(特性列表)是需要通過此規則驗證的特性列表字符串,每個特性名字由逗號分隔;
Validator(驗證器) 指定要執行驗證的種類;
on 參數是可選的,它指定此規則應被應用到的場景列表;
PHP實戰附加選項 是一個名值對數組,用于初始化相應驗證器的屬性值.
PHP實戰有三種方式可在驗證規則中指定 Validator:
PHP實戰第一, Validator 可以是模型類中一個辦法的名字,就像上面示例中的 authenticate .驗證辦法必須是下面的結構:
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', 'required'),
// 用戶名必須在 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, password', 'required', 'on'=>'login, register'),
array('email', 'required', 'on'=>'register'),
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 規則實現此目的:
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, password', 'required'),
array('password_repeat', 'required', 'on'=>'register'),
array('password', 'compare', 'on'=>'register'),
);
}
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 語句:
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().
例如, 如下代碼將生成一個文本輸入域,它可以在用戶修改了其值時觸頒發單提交動作.
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培訓學院每天發布《PHP實戰:Yii中表單用法實例詳解》等實戰技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培養人才。
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/7905.html