CakePHP 4 实现联系表单无验证报错、提交无响应问题求助
CakePHP 4 联系表单验证失效修复方案
核心问题点
- 验证规则字段名写错:ContactForm 的验证规则中对消息字段用了
text作为字段名,实际表单里对应的字段是message,规则完全未生效 - 多余重写内置方法:自行重写了父类已有的
setErrors方法,破坏了框架自动存储验证错误的逻辑 - 控制器手动覆盖错误:POST提交验证失败后,手动调用
setErrors传入自定义错误,直接覆盖了框架自动生成的验证错误信息,且传入的错误数组结构不符合规范 - 模板字段未渲染错误:消息字段用
Form::textarea()方法直接输出,没有用Form::control()包裹,不会自动渲染对应错误提示 - GET请求块作用冗余:当前GET块的作用是给表单填充默认值,如果不需要显示默认的姓名邮箱,直接删除整个
$this->request->is('get')判断块即可,不需要填写其他内容
修正后的代码
src/Form/ContactForm.php
<?php namespace App\Form; use Cake\Form\Form; use Cake\Form\Schema; use Cake\Validation\Validator; class ContactForm extends Form { protected function _buildSchema(Schema $schema): Schema { return $schema->addField('name', 'string') ->addField('email', ['type' => 'string']) ->addField('subject', ['type' => 'string']) ->addField('message', ['type' => 'text']); } public function validationDefault(Validator $validator): Validator { $validator->minLength('name', 5, '姓名至少需要5个字符') ->email('email', '请输入合法的邮箱地址') ->notEmptyString('subject', '请填写主题') ->notEmptyString('message', '请填写消息内容'); return $validator; } protected function _execute(array $data): bool { // 此处替换为实际发送邮件的业务逻辑 return true; } }
src/Controller/ContactController.php
<?php namespace App\Controller; use App\Controller\AppController; use App\Form\ContactForm; class ContactController extends AppController { public function index() { $contact = new ContactForm(); if ($this->request->is('post')) { if ($contact->execute($this->request->getData())) { $this->Flash->success('我们会尽快回复您。'); } else { $this->Flash->error('提交表单时出现问题,请检查错误提示后重试。'); // 无需手动设置错误,框架会自动把验证错误存入$contact对象 } } // 不需要默认填充值可直接删除整个GET判断块 // if ($this->request->is('get')) { // $contact->setData([ // 'name' => 'John Doe', // 'email' => 'john.doe@example.com' // ]); // } $this->set('contact', $contact); } }
templates/Pages/contact.php
... <?php echo $this->Form->create($contact); ?> <div class="row gtr-50 gtr-uniform"> <div class="col-6 col-12-mobilep"> <?php echo $this->Form->control('name',['label' => false,'placeholder'=>$translation['Name'],'templates' => ['inputContainer' => '{{content}}']]);?> </div> <div class="col-6 col-12-mobilep"> <?php echo $this->Form->control('email',['label' => false,'placeholder'=>$translation['Email'],'templates' => ['inputContainer' => '{{content}}']]);?> </div> <div class="col-12"> <?php echo $this->Form->control('subject',['label' => false,'placeholder'=>$translation['Betreff'],'templates' => ['inputContainer' => '{{content}}']]);?> </div> <div class="col-12"> <!-- 把textarea改为control类型,自动绑定错误渲染逻辑 --> <?php echo $this->Form->control('message', [ 'type' => 'textarea', 'label' => false, 'placeholder'=>$translation['Bitte gebe deine Nachricht ein'], 'rows'=>'6', 'templates' => ['inputContainer' => '{{content}}'] ]); ?> </div> <div class="col-12"> <ul class="actions special"> <li><?php echo $this->Form->submit($translation['Nachricht senden']); ?></li> </ul> </div> </div> <?php echo $this->Form->end(); ?> ...
内容的提问来源于stack exchange,提问作者Cypherfax
相关产品推荐
相关产品推荐

