CI4自定义验证规则传参异常:控制器变量变为字符串而非整数
如何在CodeIgniter 4中正确将控制器变量传递给自定义验证规则?
我正在将页面从CI3迁移至CI4。在CI3中,验证规则可从控制器接收参数,但改写代码后,传入自定义验证规则的projectid参数变为字符串'projectid'而非实际整数值。我曾尝试用隐藏输入传参,但日志仍显示参数为变量名而非实际值。
相关代码
app\Config\Validation.php
public array $manageProjectInfo = array ( 'fldPublish' => array ( 'label' => 'Make project public', 'rules' => 'trim|check_publish_datasets[projectid]' ) );
自定义验证方法
// check that there are no unpublished datasets if unpublishing project public function check_publish_datasets($fldPublish, $pid) { $valid = TRUE; $project_model = model('Project_model'); if (!$fldPublish) { log_message('debug','pid: '.$pid); $nDatasets = $project_model->get_projectdataavail($pid,$published=TRUE); if (count($nDatasets) > 0) { $valid = FALSE; $error = "This project cannot be unpublished because it contains published datasets."; } } return $valid; }
app\Controllers\Manage\Project.php
public function info($projectid = -1) { $basics['pagetitle'] = "Manage Project Information"; if ($this->request->getPost()) { $project['fldPublish'] = $this->request->getPost('fldPublish'); } //Define form attributes $data['formattribs'] = array( 'class' => 'basicForm', 'id' => 'manage-project-info-form' ); //Create array of input options, setting default values to either what they were in the database or what was entered in post data for form repopulation on error $data['fldPublish_publish'] = array( 'name' => 'fldPublish', 'id' => 'fldPublish', 'type' => 'radio', 'value' => '1', 'checked' => ($project['fldPublish'] == "1" ? TRUE : FALSE) ); $data['fldPublish_notpublish'] = array( 'name' => 'fldPublish', 'id' => 'fldPublish', 'type' => 'radio', 'value' => '0', 'checked' => ($project['fldPublish'] == "0" ? TRUE : FALSE) ); //Check if form validation has already been run and passed //Form validation rules set in form_validation config file if (!$this->request->is('post') || !$this->validateData($this->request->getPost(), 'manageProjectInfo')) { $this->common->render_page($basics, 'manage/project/info', $data); } //If successful form validation... else { //Collect post data for insert $project = array( 'fldPublish' => $this->request->getPost('fldPublish') ); $validData = $this->validator->getValidated(); foreach ($validData as $key=>$valid) { $project[$key] = $valid; } //Check flag-type columns to see if they're set to one, if they aren't set values to zero. if ($project['fldPublish'] != 1) $project['fldPublish'] = 0; //Convert null dates $builder = $this->db->table('tblProject'); $builder->where('pkProjectID', $projectid); $updateattempt = $builder->update($info_changes); if ($updateattempt) { //update the projectUpdated date and log a tblProjectChanges record $this->project_model->logProjectUpdated($projectid, "project", "info"); $this->session->setFlashdata('successmessage', "Your changes were successfully submitted"); return redirect()->to('manage/project/' . $projectid . '/info'); } else { $data['errormessage'] = "There was a problem writing your changes to the database. Please try again"; //Load the views with render_pages, passing either name of main view to load or array of main pages to load $this->common->render_page($basics, 'manage/project/info', $data); } } }
解决方法
CI4的验证规则机制和CI3不同,不能直接在配置文件的规则里引用控制器变量,下面两种方法可以解决:
方式一:动态生成验证规则(推荐)
直接在控制器里根据当前的projectid构建验证规则,把实际值传入自定义规则:
修改控制器的info方法,替换原来的验证逻辑:
public function info($projectid = -1) { // ... 保留原有其他代码 // 动态构建带实际projectid的验证规则 $validationRules = [ 'fldPublish' => [ 'label' => 'Make project public', 'rules' => "trim|check_publish_datasets[$projectid]" ] ]; // 使用动态规则验证,不再依赖配置文件的规则组 if (!$this->request->is('post') || !$this->validateData($this->request->getPost(), $validationRules)) { $this->common->render_page($basics, 'manage/project/info', $data); } // ... 后续代码保持不变 }
方式二:通过验证器实例传递额外数据
如果想保留配置文件的规则组,可以把projectid存入验证器实例,再在自定义方法中读取:
- 控制器修改验证逻辑:
public function info($projectid = -1) { // ... 保留原有其他代码 // 获取验证器实例,传入规则组和数据 $validator = \Config\Services::validator(); $validator->setData($this->request->getPost()); $validator->setRuleGroup('manageProjectInfo'); // 把projectid存入验证器的自定义属性 $validator->projectid = $projectid; // 执行验证 if (!$this->request->is('post') || !$validator->run()) { $data['validation'] = $validator; // 传递错误信息到视图 $this->common->render_page($basics, 'manage/project/info', $data); } // ... 后续代码保持不变 }
- 修改自定义验证方法,从验证器实例获取
projectid:
// check that there are no unpublished datasets if unpublishing project public function check_publish_datasets($fldPublish) { $valid = TRUE; // 从验证器实例读取projectid $pid = $this->validator->projectid; $project_model = model('Project_model'); if (!$fldPublish) { log_message('debug','pid: '.$pid); $nDatasets = $project_model->get_projectdataavail($pid, TRUE); if (count($nDatasets) > 0) { $valid = FALSE; // 设置错误信息 $this->setError("This project cannot be unpublished because it contains published datasets."); } } return $valid; }
注意:这种方式需要把配置文件里的规则改成'rules' => 'trim|check_publish_datasets',去掉后面的[projectid]参数。
内容的提问来源于stack exchange,提问作者xanabobana
相关产品推荐
相关产品推荐

