이 글은 주로 Yii의 양식 사용법을 소개하고, 이를 예시 형식으로 결합하여 일반적으로 사용되는 Yii의 다양한 운영 기법을 요약하여 필요한 친구들이 참고할 수 있습니다.
이 문서의 예에서는 Yii 양식 사용법을 설명합니다. 참고할 수 있도록 모든 사람과 공유하세요. 세부 사항은 다음과 같습니다.
Yii에서 양식을 처리할 때 일반적으로 다음 단계가 필요합니다.
1 수집할 데이터 필드를 나타내는 모델 클래스를 만듭니다.
2. 양식 제출에 응답하는 컨트롤러 작업을 만듭니다.
3. 뷰 스크립트에서 컨트롤러 액션과 관련된 폼을 생성합니다.
1. 모델 만들기
양식에 필요한 HTML 코드를 작성하기 전에 먼저 최종 사용자가 입력하는 데이터 유형과 이 데이터가 준수해야 하는 규칙을 결정해야 합니다. 모델 클래스를 사용하여 이 정보를 기록할 수 있습니다. 모델 장에서 정의한 대로 모델은 사용자 입력을 저장하고 해당 입력을 검증하는 중앙 위치입니다.
사용자가 입력한 데이터가 어떻게 사용되는지에 따라 두 가지 유형의 모델을 만들 수 있습니다. 사용자 입력을 수집하고 사용하고 폐기하는 경우 양식 모델을 만들어야 합니다.
사용자 입력을 수집하여 데이터베이스에 저장하는 경우 Active Record를 사용해야 합니다. 두 가지 유형의 모델 모두 양식에 필요한 공통 인터페이스를 정의하는 동일한 기본 클래스 CModel을 공유합니다.
1. 모델 클래스를 정의합니다.
예를 들어 양식 모델을 만듭니다.
class LoginForm extends CFormModel { public $username; public $password; public $rememberMe=false; }
LoginForm에는 $username, $password 및 $rememberMe의 세 가지 속성이 정의됩니다. 이는 사용자가 입력한 사용자 이름과 비밀번호뿐만 아니라 사용자가 자신의 로그인을 기억할지 여부에 대한 옵션을 저장하는 데 사용됩니다. $rememberMe의 기본값은 false이므로 로그인 양식에 처음 표시될 때 해당 옵션이 선택 취소됩니다.
우리는 이러한 멤버 변수를 일반 속성과 구별하기 위해 속성 대신 속성이라고 부릅니다. 속성은 주로 사용자 입력이나 데이터베이스의 데이터를 저장하는 데 사용되는 속성입니다.
2. 유효성 검사 규칙 선언
사용자가 입력을 제출하고 모델이 채워지면 사용하기 전에 사용자의 입력이 유효한지 확인해야 합니다. 이는 일련의 규칙에 대해 사용자 입력을 검증함으로써 달성됩니다. 규칙 구성 배열을 반환해야 하는 규칙() 메서드에 이러한 유효성 검사 규칙을 지정합니다.
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) { ... }
둘째, 유효성 검사기는 유효성 검사기 클래스의 이름일 수 있습니다. 이 규칙이 적용되면 실제 유효성 검사를 수행하기 위한 유효성 검사기 클래스의 인스턴스가 생성됩니다. 규칙의 추가 옵션은 인스턴스의 속성 값을 초기화하는 데 사용됩니다. 유효성 검사기 클래스는 CValidator에서 상속되어야 합니다.
셋째, Validator는 미리 정의된 Validator 클래스의 별칭일 수 있습니다. 위의 예에서 필수 이름은 유효성을 검사하는 속성이 비어 있지 않은지 확인하는 데 사용되는 CRequiredValidator의 별칭입니다. 다음은 사전 정의된 유효성 검사기 별칭의 전체 목록입니다.
boolean: CBooleanValidator에 대한 별칭으로, 속성에 CBooleanValidator::trueva lue 또는 CBooleanValidator::falseva lue 값이 있는지 확인합니다.
captcha: CCaptchaValidator의 별칭으로, 특성 값이 CAPTCHA에 표시된 확인 코드와 동일한지 확인합니다.
비교: CComparevalidator의 별칭은 속성이 다른 속성 또는 상수와 동일하도록 보장합니다.
email: CEmailValidator의 별칭은 속성이 유효한 이메일 주소인지 확인합니다.
default: CDefaultValueva 뚜껑의 별칭으로, 기능의 기본값을 지정합니다.
exist: CExistValidator의 별칭으로, 지정된 테이블의 열에서 속성 값을 찾을 수 있는지 확인합니다.
file: CFilevalidator의 별칭입니다. 속성에 업로드된 파일의 이름이 포함되어 있는지 확인하세요.
filter: CFilterValidator의 별칭으로, 필터를 통해 이 속성을 변경합니다.
in: CRangevalidator의 별칭으로, 데이터가 미리 지정된 값 범위 내에 있는지 확인합니다.
length: CStringValidator의 별칭으로, 데이터 길이가 지정된 범위 내에 있는지 확인합니다.
match: CRegularExpressionValidator의 별칭으로, 데이터가 정규 표현식과 일치할 수 있는지 확인합니다.
숫자: CNumberValidator의 별칭으로, 데이터가 유효한 숫자인지 확인합니다.
required: CRequiredValidator의 별칭으로, 속성이 비어 있지 않은지 확인합니다.
type: CTypevalidator의 별칭으로, 속성이 지정된 데이터 유형인지 확인합니다.
unique: CUniquevalidator의 별칭으로, 데이터 테이블의 열 간에 데이터가 고유하도록 보장합니다.
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中文网!
相关推荐:
Bootbox 플러그인을 사용하여 Yii2에서 사용자 정의 팝업을 구현하는 방법
위 내용은 Yii의 양식 사용 예의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!