Yii2 表单处理实战从模型校验到 ActiveForm 视图的完整 MVC 流程【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址: https://gitcode.com/gh_mirrors/yi/yii2本篇技术指南围绕 Yii2 框架中如何通过 HTML 表单收集用户数据这一经典场景展开以 docs/guide-ru/start-forms.md 为骨架完整演示创建表单模型 → 声明校验规则 → 编写控制器动作 → 构建视图表单 → 前后端双重校验的 MVC 实现链路。读完本文你将掌握yii\base\Model表单模型、rules()校验规则声明、ActiveForm视图组件、Yii::$app-request-post()数据装载以及客户端/服务端双重验证的完整实战方案并了解底层源码的工作原理。场景概述一次典型的表单提交闭环本节要解决的问题非常具体页面上放置一张包含name姓名和email邮箱两个输入框的表单用户填写并提交后页面回显用户输入的数据用于确认。整个流程覆盖 MVC 三个角色模型Modelmodels/EntryForm.php承载用户输入并声明校验规则视图Viewviews/site/entry.php表单页与views/site/entry-confirm.php确认页控制器ControllerSiteController::actionEntry()串联装载、校验与渲染。除了创建 动作 和两个 视图你还需要创建一份 模型。学习完本节你将掌握三件事如何创建用于承载用户输入数据的模型类如何声明数据校验规则如何在 视图 中构建 HTML 表单。第一步创建表单模型 EntryForm在models/EntryForm.php文件中创建如下模型类关于类文件命名约定详见 类自动加载 一节?php namespace app\models; use yii\base\Model; class EntryForm extends Model { public $name; public $email; public function rules() { return [ [[name, email], required], [email, email], ]; } }该模型继承自 [[yii\base\Model]]框架自带基类位于 framework/base/Model.php是 Yii 中用于承载非数据库表关联数据如表单数据的标准父类若模型对应数据库表则应继承yii\db\ActiveRecord。类中声明了两个公开属性name与email用于存放用户输入并实现了rules()方法返回一组校验规则name和email均为必填项email必须是语法上合法的邮箱地址。深入源码validate() 到底做了什么当EntryForm对象被用户数据填充后调用 [[yii\base\Model::validate()|validate()]] 即可触发校验流程。对照 framework/base/Model.php 的实现可以看到其核心步骤默认先调用clearErrors()清除旧错误触发beforeValidate事件可返回false中断校验通过scenarios()判断当前场景取出activeAttributes()中处于激活状态的属性遍历getActiveValidators()得到的活动校验器逐个执行validateAttributes()触发afterValidate事件最终返回!$this-hasErrors()。校验失败时 [[yii\base\Model::hasErrors|hasErrors]] 属性为true可通过 [[yii\base\Model::getErrors|errors]] 查看具体错误。除validate()外Model还提供getFirstErrors()、getFirstError()等便捷方法见 framework/base/Model.php。直接手动填充并校验的写法如下?php $model new EntryForm(); $model-name Qiang; $model-email bad; if ($model-validate()) { // 校验通过 } else { // 校验失败使用 $model-getErrors() }深入源码required 与 email 两个内置校验器rules()中required与email是 Yii 的两个内置校验器分别对应 framework/validators/RequiredValidator.php 与 framework/validators/EmailValidator.php。RequiredValidator当requiredValue为null默认时仅要求值非空默认错误消息为{attribute} cannot be blank.必填字段为空时的提示即由此产生见 RequiredValidator.php也可指定requiredValue与strict实现必须等于某个值的强校验。EmailValidator默认使用正则pattern校验邮箱格式默认错误消息为{attribute} is not a valid email address.见 EmailValidator.php还支持allowName允许Name email格式等选项。这些校验器都实现了clientValidateAttribute()能输出对应的 JavaScript 校验代码如yii.validation.required(...)、yii.validation.email(...)这是后续客户端校验能力的来源。第二步创建控制器动作 actionEntry接下来在site控制器中创建entry动作创建动作的方法与 Saying Hello入门篇 一致?php namespace app\controllers; use Yii; use yii\web\Controller; use app\models\EntryForm; class SiteController extends Controller { // ...已有代码... public function actionEntry() { $model new EntryForm(); if ($model-load(Yii::$app-request-post()) $model-validate()) { // $model 中的数据已通过校验 // 在这里对 $model 做有意义的事情 ... return $this-render(entry-confirm, [model $model]); } else { // 要么是页面首次展示要么是数据存在校验错误 return $this-render(entry, [model $model]); } } }动作先创建EntryForm对象再通过Yii::$app-request-post()获取$_POST数据并装载进模型装载成功即用户提交了表单后调用validate()校验数据。数据合法则渲染entry-confirm视图回显输入否则渲染entry视图展示表单及错误提示。InfoYii::$app是全局可访问的应用单例singleton同时也是一个 Service Locator提供request、response、db等组件。上例通过应用实例的request组件读取$_POST数据。Note本示例在数据合法时直接渲染确认页。实际项目中应考虑使用 [[yii\web\Controller::refresh()|refresh()]] 或 [[yii\web\Controller::redirect()|redirect()]] 做重定向避免表单重复提交问题Post/Redirect/Get 模式。深入源码load() 的数据装载逻辑load()的实现见 framework/base/Model.php它以formName()默认取类短名可覆写为键从$data中取出$data[EntryForm]子数组再经setAttributes()的安全检查只写入safe()场景中标记为安全的属性填充模型若formName()为空则直接装载整个$data。这就是为什么 ActiveForm 渲染出的输入框name属性形如EntryForm[name]——load()依赖这一命名空间结构完成批量装载。第三步创建两个视图动作entry会渲染两个视图分别存放在views/site/目录下。确认视图 entry-confirmviews/site/entry-confirm.php仅回显姓名与邮箱?php use yii\helpers\Html; ? pВы ввели следующую информацию:/p ul lilabelName/label: ? Html::encode($model-name) ?/li lilabelEmail/label: ? Html::encode($model-email) ?/li /ul表单视图 entryviews/site/entry.php使用 ActiveForm 构建 HTML 表单?php use yii\helpers\Html; use yii\widgets\ActiveForm; ? ?php $form ActiveForm::begin(); ? ? $form-field($model, name) ? ? $form-field($model, email) ? div classform-group ? Html::submitButton(Отправить, [class btn btn-primary]) ? /div ?php ActiveForm::end(); ?视图借助强大的 widget [[yii\widgets\ActiveForm|ActiveForm]]实现见 framework/widgets/ActiveForm.php构建表单begin()与end()分别输出form开始与结束标签两者之间用field()方法创建输入字段第一个是name第二个是email最后由 [[yii\helpers\Html::submitButton()]] 生成提交按钮。第四步运行验证在浏览器中访问以下 URL 查看效果https://hostname/index.php?rsite%2Fentry你会看到一张包含两个输入框的页面每个输入框前都有提示标签。若直接点击提交字段为空或邮箱格式不正确每个有问题的字段旁都会出现错误提示。输入合法的姓名与邮箱并提交后将看到回显刚才输入数据的确认页面深入剖析ActiveForm 的魔法从何而来整个流程看似魔法——标签自动生成、输入错误即时提示、无需整页刷新。其原理如下客户端与服务端双重校验校验首先在客户端通过 JavaScript 完成其次在服务端通过 PHP 完成。[[yii\widgets\ActiveForm]] 足够智能它会读取你在EntryForm::rules()中声明的校验规则将其转换成可执行的 JavaScript 代码yii.validation运行时见 framework/assets/yii.activeForm.js 与 framework/assets/yii.validation.js再用这些 JS 执行即时校验。即便用户在浏览器中禁用 JavaScriptactionEntry()中的服务端validate()依然兜底校验保证任何情况下数据都正确。Warning客户端校验只是提升用户体验的便利手段无论是否存在客户端校验服务端校验始终是必须的。标签由属性名自动生成field()方法基于模型属性名生成标签。例如属性name会生成标签Name。可在视图中自定义标签? $form-field($model, name)-label(Ваше имя) ? ? $form-field($model, email)-label(Ваш Email) ?InfoYii 提供了大量此类 widget帮助你快速构建复杂且动态的视图。如后文所述编写新 widget 也非常简单。你可以把大量视图代码抽取成可复用 widget简化后续开发。小结在本节中你完整走了一遍 MVC 设计模式的每个环节创建承载并校验用户数据的模型类、从用户处获取数据、再把数据展示回浏览器。这类工作在实际开发中往往耗时巨大而 Yii 提供的强大 widget 让整个任务变得极其简单。下一节将学习几乎所有应用都会用到的数据库操作见 入门使用数据库。【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址: https://gitcode.com/gh_mirrors/yi/yii2创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
