如何针对单个验证规则多次覆盖要显示的错误消息。
我试图在下面的代码中执行此操作,但它显示了在结尾处设置的错误消息,即'b'
我在这里尝试做的是,为'first_name'显示错误'a',为last_name显示错误'b'。
<?php
/*
This program will test whether we could override the codeingiter error messages from the validation helper.
We are going to use the 'set_message' function.
*/
class Message_override extends CI_Controller{
public function __construct(){
parent::__construct();
$this->load->helper('url');
}
public function index(){
$this->load->view('message_override_view');
}
public function display_error(){
$this->load->library('form_validation');
$this->form_validation->set_message('numeric','a');
$this->form_validation->set_rules('txt_first_name', 'First Name', 'numeric');
$this->form_validation->set_message('numeric','b');
$this->form_validation->set_rules('txt_last_name', 'Last Name', 'numeric');
if($this->form_validation->run()==FALSE)
{
print_r(validation_errors());
}
else
{
echo '<pre>';
print_r($_POST);
}
}
}
?>
答案 0 :(得分:3)
CodeIgniter本身不支持同一规则的多条错误消息,但您可以尝试一些解决方法:
正如@HashemQolami建议的那样,您可以使用多个callback functions并为每个错误消息设置不同的错误消息:
$this->form_validation->set_rules('txt_first_name', 'First Name', 'callback_numeric_a');
$this->form_validation->set_rules('txt_last_name', 'Last Name', 'callback_numeric_b');
这种方法的缺点是显然它不是模块化的,而是重复的,因为你需要在你的控制器中定义多个函数,就像这个一样
public function numeric_a($str){
$this->form_validation->set_message('numeric_a', 'a');
return $this->numeric($str);
}
我使用的另一种解决方法是在语言文件中将规则的消息设置为%s
,然后将自定义消息设置为字段的标签
$lang['numeric'] = '%s';
$this->form_validation->set_rules('txt_first_name', 'a', 'numeric');
$this->form_validation->set_rules('txt_last_name', 'b', 'numeric');
这里的缺点是它基本上会混淆错误消息系统,因为你必须为每个字段定义标签,并且每个字段只能使用一个验证规则。我仍然发现它在联系表单中很有用,你只需要验证某些必填字段的存在。
既然我已经发现自己需要更好地实现此功能,那么您的帖子激发了我对表单验证类的简单扩展,不幸的是我不得不“破解”主要的execute
方法,因为没有用于检索错误消息的特殊功能。
我添加了一个方法set_custom_message()
,可以将规则的自定义消息设置为特定字段或字段数组。
$this->form_validation->set_custom_message('txt_first_name','numeric','a');
$this->form_validation->set_custom_message('txt_last_name','numeric','b');
//Example passing an array of fields
$this->form_validation->set_custom_message(array('txt_first_name','txt_last_name'),'numeric','c');
以下是其他人感兴趣的扩展类的代码:
请注意,这是基于 CodeIgniter v2.1.4
中包含的表单验证类<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* MY_Form_validation Class
*
* Extends Form_Validation library
*
* Adds custom message support.
*
*/
class MY_Form_validation extends CI_Form_validation {
protected $_custom_messages = array();
public function set_custom_message($field = '', $rule = '', $message = '' ){
if(is_array($field)){
foreach($field as $id){
$this->_custom_messages[$id][$rule] = $message;
}
return;
}
$this->_custom_messages[$field][$rule] = $message;
return;
}
protected function _execute($row, $rules, $postdata = NULL, $cycles = 0)
{
// If the $_POST data is an array we will run a recursive call
if (is_array($postdata))
{
foreach ($postdata as $key => $val)
{
$this->_execute($row, $rules, $val, $cycles);
$cycles++;
}
return;
}
// --------------------------------------------------------------------
// If the field is blank, but NOT required, no further tests are necessary
$callback = FALSE;
if ( ! in_array('required', $rules) AND is_null($postdata))
{
// Before we bail out, does the rule contain a callback?
if (preg_match("/(callback_\w+(\[.*?\])?)/", implode(' ', $rules), $match))
{
$callback = TRUE;
$rules = (array('1' => $match[1]));
}
else
{
return;
}
}
// --------------------------------------------------------------------
// Isset Test. Typically this rule will only apply to checkboxes.
if (is_null($postdata) AND $callback == FALSE)
{
if (in_array('isset', $rules, TRUE) OR in_array('required', $rules))
{
// Set the message type
$type = (in_array('required', $rules)) ? 'required' : 'isset';
if(array_key_exists($row['field'],$this->_custom_messages) &&
array_key_exists($type,$this->_custom_messages[$row['field']])){
$line = $this->_custom_messages[$row['field']][$type];
}else{
if ( ! isset($this->_error_messages[$type]))
{
if (FALSE === ($line = $this->CI->lang->line($type)))
{
$line = 'The field was not set';
}
}
else
{
$line = $this->_error_messages[$type];
}
}
// Build the error message
$message = sprintf($line, $this->_translate_fieldname($row['label']));
// Save the error message
$this->_field_data[$row['field']]['error'] = $message;
if ( ! isset($this->_error_array[$row['field']]))
{
$this->_error_array[$row['field']] = $message;
}
}
return;
}
// --------------------------------------------------------------------
// Cycle through each rule and run it
foreach ($rules As $rule)
{
$_in_array = FALSE;
// We set the $postdata variable with the current data in our master array so that
// each cycle of the loop is dealing with the processed data from the last cycle
if ($row['is_array'] == TRUE AND is_array($this->_field_data[$row['field']]['postdata']))
{
// We shouldn't need this safety, but just in case there isn't an array index
// associated with this cycle we'll bail out
if ( ! isset($this->_field_data[$row['field']]['postdata'][$cycles]))
{
continue;
}
$postdata = $this->_field_data[$row['field']]['postdata'][$cycles];
$_in_array = TRUE;
}
else
{
$postdata = $this->_field_data[$row['field']]['postdata'];
}
// --------------------------------------------------------------------
// Is the rule a callback?
$callback = FALSE;
if (substr($rule, 0, 9) == 'callback_')
{
$rule = substr($rule, 9);
$callback = TRUE;
}
// Strip the parameter (if exists) from the rule
// Rules can contain a parameter: max_length[5]
$param = FALSE;
if (preg_match("/(.*?)\[(.*)\]/", $rule, $match))
{
$rule = $match[1];
$param = $match[2];
}
// Call the function that corresponds to the rule
if ($callback === TRUE)
{
if ( ! method_exists($this->CI, $rule))
{
continue;
}
// Run the function and grab the result
$result = $this->CI->$rule($postdata, $param);
// Re-assign the result to the master data array
if ($_in_array == TRUE)
{
$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
}
else
{
$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
}
// If the field isn't required and we just processed a callback we'll move on...
if ( ! in_array('required', $rules, TRUE) AND $result !== FALSE)
{
continue;
}
}
else
{
if ( ! method_exists($this, $rule))
{
// If our own wrapper function doesn't exist we see if a native PHP function does.
// Users can use any native PHP function call that has one param.
if (function_exists($rule))
{
$result = $rule($postdata);
if ($_in_array == TRUE)
{
$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
}
else
{
$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
}
}
else
{
log_message('debug', "Unable to find validation rule: ".$rule);
}
continue;
}
$result = $this->$rule($postdata, $param);
if ($_in_array == TRUE)
{
$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
}
else
{
$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
}
}
// Did the rule test negatively? If so, grab the error.
if ($result === FALSE)
{
if(array_key_exists($row['field'],$this->_custom_messages) &&
array_key_exists($rule,$this->_custom_messages[$row['field']])){
$line = $this->_custom_messages[$row['field']][$rule];
}else{
if ( ! isset($this->_error_messages[$rule]))
{
if (FALSE === ($line = $this->CI->lang->line($rule)))
{
$line = 'Unable to access an error message corresponding to your field name.';
}
}
else
{
$line = $this->_error_messages[$rule];
}
}
// Is the parameter we are inserting into the error message the name
// of another field? If so we need to grab its "field label"
if (isset($this->_field_data[$param]) AND isset($this->_field_data[$param]['label']))
{
$param = $this->_translate_fieldname($this->_field_data[$param]['label']);
}
// Build the error message
$message = sprintf($line, $this->_translate_fieldname($row['label']), $param);
// Save the error message
$this->_field_data[$row['field']]['error'] = $message;
if ( ! isset($this->_error_array[$row['field']]))
{
$this->_error_array[$row['field']] = $message;
}
return;
}
}
}
// END MY Form Validation Class
/* End of file MY_Form_validation.php */
/* Location: ./application/libraries/MY_Form_validation.php */
}