如何让CodeIgniter在不拥有required
规则但用户留空的字段上运行自定义规则?
我能想到的最好的方法是在字符串为空的情况下为字段添加空格,然后添加trim
规则 - 但这会让人感到烦恼。
仅当另一个字段具有特定值时才需要字段:
// depends[another_field.some_val]
public function depends($str, $field){
list($post_key, $post_val)=explode('.', $field);
if($_POST[$post_key] == $post_val){
return $str != "";
}
return true;
}
只有在数据库中存在正则表达式时才需要字段:
// regex[table_name.col_name.some_val]
public function regex($str, $field){
list($table, $col, $post_val)=explode('.', $field);
// Grab the regex
$regex = $this->CI ->db
->limit(1)
->select($col)
->where($post_val, $_POST[$post_val])
->get($table)
->row($col);
return preg_match('/'.$regex.'/', $str) === 1;
}
答案 0 :(得分:1)
为什么对于简单的任务需要不同的功能。使用 if..else
。
假设 input1
的值等于 value1
,则只需设置 required
< / strong>另一个输入的验证规则,例如 input2
。
查看:强>
<form action="/controller_name/function_name/" method="POST">
<input type="text" name="input1" />
<input type="text" name="input2" />
<input type="submit" />
</form>
的控制器:强>
class Controller_name extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->library('form_validation');
}
public function function_name()
{
if($this->input->is_post())
{
if($this->input->post('input1') == 'value1')
{
$this->form_validation->set_rules('input2', 'input2', 'required');
}
if ($this->form_validation->run() == FALSE)
{
// something's wrong in form!
}
else
{
// form is good, proceed!
}
}
}
}
答案 1 :(得分:1)
从代码中,您指出的问题是您需要创建一个字段。好吧,使用新规则创建一个必需的字段:'keep_checking'。这样,您强制系统检查您想要的任何内容。我做了什么:
application/libraries
文件夹最后一点,在扩展Form_validation类之后,您将有一个位置可以放置您将一直使用的所有新自定义规则,XD
class MY_Form_validation extends CI_Form_validation
{
public function __construct( $rules = array( ) ) {
parent::__construct( $rules );
}
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;
//====================================================================
// NEW ADDED RULE > 'keep_checking', will check all the rules even if
// the field is empty
//====================================================================
if ( ! in_array('required', $rules) AND is_null($postdata) AND ! in_array( 'keep_checking', $rules ) )
{
// 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.
//====================================================================
// NEW ADDED RULE > 'keep_checking', will check all the rules even if
// the field is empty
//====================================================================
if (is_null($postdata) AND $callback == FALSE && !in_array( 'keep_checking', $rules ))
{
if (in_array('isset', $rules, TRUE) OR in_array('required', $rules))
{
// Set the message type
$type = (in_array('required', $rules)) ? 'required' : 'isset';
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 ( ! 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;
}
}
}
}
更新:
Checkbox行避免继续检查。只需添加我添加的新行,它就可以了。您必须将keep_checking规则添加到要检查的任何字段:
class Welcome extends CI_Controller {
/**
* Index Page for this controller.
*
* Maps to the following URL
* http://example.com/index.php/welcome
* - or -
* http://example.com/index.php/welcome/index
* - or -
* Since this controller is set as the default controller in
* config/routes.php, it's displayed at http://example.com/
*
* So any other public methods not prefixed with an underscore will
* map to /index.php/welcome/<method_name>
* @see http://codeigniter.com/user_guide/general/urls.html
*/
public function index()
{
$this->load->view('welcome_message');
}
public function test()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('name', 'Name', 'keep_checking|required');
$this->form_validation->set_rules('surname', 'Surname', 'keep_checking|is_numeric');
if ( $this->form_validation->run() ) {
} else {
$this->load->view('form');
}
}
}
查看:form.php
<form action="test" method="post">
<?php echo validation_errors(); ?>
<p>
Name: <input name="name">
</p>
<p>
Surname: <input name="surname">
</p>
<p>
<input type="submit" value="Send">
</p>
</form>
提交该表单后,您将看到CI检查输入字段中的所有规则。最后一点,不要忘记MY_Form_validation进入库文件夹
答案 2 :(得分:1)
在我的更新方法中,我只想提交脏的字段。如果一个不需要验证的字段被发送为空,则并非所有字段都是必需的并且验证失败。
因此,如果用户想要移除他们的手机,它会像 phone:""
一样发送,如果我尝试像这样传递它,验证将不会看到它。
if($this-put("phone")) $this->form_validation->set_rules('phone', 'Phone', 'trim');
所以我不得不使用 array_key_exist() 来查看并传递它,即使它是空的。
if($this->put("description")) $this->form_validation->set_rules('description', 'Description', 'trim|required');
if(array_key_exists("phone", $this->input->post())) $this->form_validation->set_rules('phone', 'Phone', 'trim');
答案 3 :(得分:0)
我认为你要找的是callbacks
您可以在规则中定义回调
$this->form_validation->set_rules('field1', 'Field 1', 'trim|callback_field1_check');
$this->form_validation->set_rules('field2', 'Field 2', 'callback_field2_check');
现在你可以拥有一个带布尔返回值的函数。
public function field1_check($input) {
if ($input != '') {
$this->field1Set = true;
}
}
public function field2_check($input) {
// do something on $input
$input = trim($input);
// awesome thing is, you get to access all the field variables of your control here
// so in some other function, you'll toggle a boolean to note that an optional field was filled
// that variable set by other validation callback, you can use here
if ($this->field1Set === true && $input == '') return false;
return true;
}
答案 4 :(得分:0)
我已经通过编辑system/libraries/Form_validation.php
来找到了解决这个问题的方法。
我在第487行将$callback
更改为TRUE
:
$callback = TRUE;
并注释出第488-500行:
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;
}
}
如果有人可以在不编辑CodeIgniter的system
文件的情况下考虑解决方案,那么赏金仍然存在。
答案 5 :(得分:0)
function add($id = '') {
$this->form_validation->set_rules('title', 'Title', 'trim|required');
$this->form_validation->set_rules('title_description', 'title_description', 'trim|required');
$this->form_validation->set_rules('color', 'color', 'trim|required');
$this->form_validation->set_rules('button', 'button', 'trim|required');
//$this->form_validation->set_rules('description', 'Description', 'trim|required');
if ($this->form_validation->run() == FALSE) {
echo "Not Valid";
} else {
echo "Valid";
}
}
答案 6 :(得分:0)
您可以在视图中添加具有永久值的隐藏输入,并在验证规则中对其进行测试。
在视图中:
<input type="hidden" name="id_form" value="1"/>
在模型或控制器中(取决于您的架构)
public function validates_rules(){
$this->form_validation->set_rules('id_form', 'Title', 'callback_values_check');
...
}
public function values_check($id_form){
if($this->input->post('other_value_to_test')){
...
}
}