解决:validation在model里使用, callback会出问题
一般教程上使用时,数据检测都是在controler里测试,可是MVC的原则就是数据处理的任务是交给model处理的,所以今天我在表单提交处理数据的时间,是在model里面处理:代码如下:controller:
class Form extends Controller
{
function Form()
{
parent::Controller();
$this->load->helper(array('url', 'form'));
$this->load->model('form_model');
}
function index()
{
$this->load->view('myform');
}
function dosubmit()
{
$this->form_model->dosubmit();
}
}
==============================================================
model:
class Form_model extends Model
{
function Form_model()
{
parent::Model();
$this->load->library('validation');
}
function dosubmit()
{
$rules['username'] = "callback_username_check";
$rules['password'] = "required";
$this->validation->set_rules($rules);
if ($this->validation->run() == false)
{
$this->load->view('myform');
}
else
{
return true;
}
}//end dosubmit
function username_check($str)
{
if($str=='test')
{
$this->validation->set_message('username_check', ' %s 不能为 "test"');
return false;
}
else
{
return true;
}
}//end username_check
}//end model
===================================================================
myform:
<html>
<head>
<title>My Form</title>
<meta http-equiv="Content-Type" c />
</head>
<body>
<?=$this->validation->error_string; ?>
<?=form_open('form/dosubmit');?>
<input type="text" name="username"><br />
<input type="text" name="password"><br />
</form>
</body>
</html>
===================================================
测试结果是:
当用户名username为“test”时,检测不出有错误 ,password为空时可以检测出错误。
就是说明,在model里不能用到validation 的回调函数???
请高手指出问题所在。 在英文wiki上找了一下,终于找到了解决方法:
http://codeigniter.com/wiki/MY_Validation_-_Callbacks_into_Models/
方法是要扩展一下validation,文章好像在说,在比目前版本更高版本将来会更新。
做法如下:
model:
class Form_model extends Model
{
function Form_model()
{
parent::Model();
$this->load->library('validation');
}
function dosubmit()
{
$this->validation->set_rules(array(
'username' => 'trim|required|callback_form_model->is_unique',
'password' => 'trim|required|matches',
));
$this->validation->set_rules($rules);
if ($this->validation->run() == false)
{
$this->load->view('myform');
}
else
{
return true;
}
}//end dosubmit
function is_unique($value)
{
if($value =='test')
{
$this->validation->set_message('form_mode->is_unique', ' The %s 不能为"rest"');
return false;
}
else
{
return true;
}
/*
$this->db->where($field,$value);
$this->db->from($this->_table);
return ($this->db->count_all_results() == 0);
*/这里是从数库里找出是否存在username这一记录。如果存在则返回false;
}
}//end model //把下面代码存为application/libraries/MY_Validation.php
<?phpif (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* MY_Validation extension
*
* Allows callback functions into Models
*
* Usage:
* Pass the caller to the validation class
* $this->validation->run($this);
*
* Version 0.3 (c) Wiredesignz 2008-04-24
*/
class MY_Validation extends CI_Validation
{
function get_fields()
{
return $this->_fields;
}
/**
* Run the Validator
*
* This function does all the work.
*
* @access public
* @return bool
*/
function run(&$parent = NULL)
{
// Do we even have any data to process?Hmm?
if (count($_POST) == 0 OR count($this->_rules) == 0)
{
return FALSE;
}
isset($parent) OR $parent = $this->CI;
// Load the language file containing error messages
$parent->load->language('validation');
// Cycle through the rules and test for errors
foreach ($this->_rules as $field => $rules)
{
//Explode out the rules!
$ex = explode('|', $rules);
// Is the field required?If not, if the field is blankwe'll move on to the next test
if ( ! in_array('required', $ex, TRUE))
{
if ( ! isset($_POST[$field]) OR $_POST[$field] == '')
{
continue;
}
}
/*
* Are we dealing with an "isset" rule?
*
* Before going further, we'll see if one of the rules
* is to check whether the item is set (typically this
* applies only to checkboxes).If so, we'll
* test for it here since there's not reason to go
* further
*/
if ( ! isset($_POST[$field]))
{
if (in_array('isset', $ex, TRUE) OR in_array('required', $ex))
{
if ( ! isset($this->_error_messages['isset']))
{
if (FALSE === ($line = $parent->lang->line('isset')))
{
$line = 'The field was not set';
}
}
else
{
$line = $this->_error_messages['isset'];
}
// Build the error message
$mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];
$message = sprintf($line, $mfield);
// Set the error variable.Example: $this->username_error
$error = $field.'_error';
$this->$error = $this->_error_prefix.$message.$this->_error_suffix;
$this->_error_array[] = $message;
}
continue;
}
/*
* Set the current field
*
* The various prepping functions need to know the
* current field name so they can do this:
*
* $_POST[$this->_current_field] == 'bla bla';
*/
$this->_current_field = $field;
// Cycle through the rules!
foreach ($ex As $rule)
{
// 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
$param = FALSE;
if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match))
{
$rule = $match;
$param = $match;
}
// Call the function that corresponds to the rule
if ($callback === TRUE)
{
/* Allows callbacks into Models */
if (list($class, $method) = split('->', $rule))
{
if ( ! method_exists($parent->$class, $method))
{
continue;
}
$result = $parent->$class->$method($_POST[$field], $param);
}
else
{
if ( ! method_exists($parent, $rule))
{
continue;
}
$result = $parent->$rule($_POST[$field], $param);
}
/* Original code continues */
// If the field isn't required and we just processed a callback we'll move on...
if ( ! in_array('required', $ex, TRUE) AND $result !== FALSE)
{
continue 2;
}
}
else
{
if ( ! method_exists($this, $rule))
{
/*
* Run the native PHP function if called for
*
* 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))
{
$_POST[$field] = $rule($_POST[$field]);
$this->$field = $_POST[$field];
}
continue;
}
$result = $this->$rule($_POST[$field], $param);
}
// Did the rule test negatively?If so, grab the error.
if ($result === FALSE)
{
if ( ! isset($this->_error_messages[$rule]))
{
if (FALSE === ($line = $parent->lang->line($rule)))
{
$line = 'Unable to access an error message corresponding to your field name.';
}
}
else
{
$line = $this->_error_messages[$rule];
}
// Build the error message
$mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];
$mparam = ( ! isset($this->_fields[$param])) ? $param : $this->_fields[$param];
$message = sprintf($line, $mfield, $mparam);
// Set the error variable.Example: $this->username_error
$error = $field.'_error';
$this->$error = $this->_error_prefix.$message.$this->_error_suffix;
// Add the error to the error array
$this->_error_array[] = $message;
continue 2;
}
}
}
$total_errors = count($this->_error_array);
/*
* Recompile the class variables
*
* If any prepping functions were called the $_POST data
* might now be different then the corresponding class
* variables so we'll set them anew.
*/
if ($total_errors > 0)
{
$this->_safe_form_data = TRUE;
}
$this->set_fields();
// Did we end up with any errors?
if ($total_errors == 0)
{
return TRUE;
}
// Generate the error string
foreach ($this->_error_array as $val)
{
$this->error_string .= $this->_error_prefix.$val.$this->_error_suffix."\n";
}
return FALSE;
}
} 重要注意:
你在controller里$this->load->model('form_model');时,如果自己定义了一个名字,如“validmodel”,一定要保持model里:
==============================(以下是默认)===================================
$this->validation->set_rules(array(
'username' => 'trim|required|callback_form_model->is_unique',
'password' => 'trim|required|matches',
));
===================================================================
$this->validation->set_message(’form_model->is_unique‘, ' %s 不能为 "test"');
===================================================================
要改为:
$this->validation->set_rules(array(
'username' => 'trim|required|callback_validmodel->is_unique',
'password' => 'trim|required|matches',
));
===================================================================
$this->validation->set_message(’validmodel->is_unique‘, ' %s 不能为 "test"');
===================================================================
可以看出,在model 里,validation回调函数里是在contoller实例化时的对象函数。
页:
[1]