文件上传需要在CodeIgniter中进行验证


File upload required validation in CodeIgniter

我有两个文本字段和一个文件上传,这都是必需的。当我只需要文本字段时,一切都正常,但当我需要上传文件时,验证错误仍然表明需要一个文件,即使我选择了一个。我做错了什么?

//查看

<?php echo form_open_multipart('add'); ?>
<fieldset>
    <input type="text" name="name" /><br>
    <input type="text" name="code" /><br>
    <input type="file" name="userfile" /><br><br>
    <input type="submit"value="Add" />
</fieldset>
<?php echo form_close(); ?>

//控制器

public function add() {
    $this->form_validation->set_rules('name', 'Name', 'required');
    $this->form_validation->set_rules('code', 'Code', 'required');
    //$this->form_validation->set_rules('userfile', 'Document', 'required');
    //when the above line is active the upload does not go through
    if ($this->form_validation->run() == FALSE) {
        $data['page_view'] = $this->page_view;
        $data['page_title'] = $this->page_title;
        $this->load->view('template', $data);
    }
    else
    {
        $this->load->library('upload');
        if (!empty($_FILES['userfile']['name']))
        {
            $config['upload_path'] = './uploads/';
            $config['allowed_types'] = 'gif|jpg|png|jpeg';     
            $this->upload->initialize($config);
            if ($this->upload->do_upload('userfile'))
            {
                $img = $this->upload->data();
                $file_name = $img['file_name'];
                $name = $this->input->post('name');
                $code = $this->input->post('code');
                $this->load->model('create', 'create_model');
                $this->create_model->create_entry($name, $code, $file_name);
                $data['page_view'] = $this->page_view;
                $data['page_title'] = $this->page_title;
                $this->load->view('template', $data);
            }
            else
            {
                echo $this->upload->display_errors();
            }
        }
    }
}

我找到了一个完全按照我想要的方式工作的解决方案。

我更改了

$this->form_validation->set_rules('name', 'Name', 'trim|required');
$this->form_validation->set_rules('code', 'Code', 'trim|required');
$this->form_validation->set_rules('userfile', 'Document', 'required');

$this->form_validation->set_rules('name', 'Name', 'trim|required');
$this->form_validation->set_rules('code', 'Code', 'trim|required');
if (empty($_FILES['userfile']['name']))
{
    $this->form_validation->set_rules('userfile', 'Document', 'required');
}

CodeIgniter文件上传(可选)。。。完美工作……:)

----------控制器--------

function file()
{
 $this->load->view('includes/template', $data);
}
function valid_file()
{
 $this->form_validation->set_rules('userfile', 'File', 'trim|xss_clean');
 if ($this->form_validation->run()==FALSE) 
 {
    $this->file();
 }
 else
 {
  $config['upload_path']   = './documents/';
  $config['allowed_types'] = 'gif|jpg|png|docx|doc|txt|rtf';
  $config['max_size']      = '1000';
  $config['max_width']     = '1024';
  $config['max_height']    = '768';
  $this->load->library('upload', $config);
  if ( !$this->upload->do_upload('userfile',FALSE))
  {
    $this->form_validation->set_message('checkdoc', $data['error'] = $this->upload->display_errors());
    if($_FILES['userfile']['error'] != 4)
    {
        return false;
    }
  }
  else
  {
    return true;
  }
}

我只是使用这条线,这使它成为可选的,

if($_FILES['userfile']['error'] != 4)
{
 return false;
}
$_FILES['userfile']['error'] != 4 is for file required to upload.

您可以使用$_FILES['userfile']['error'] != 4使其不必要,然后它将为所需的文件传递此错误,并且使用return false可以很好地处理其他类型的错误,希望它对你有用。。。。

检查这个表单验证扩展库可以帮助您验证文件,使用当前表单验证,当您验证上传字段时,它会将其视为值为空的输入字段。看看这个非常好的表单验证库扩展

MY_形式验证

您可以使用回调函数,像这个

  $this->form_validation->set_rules('userfile', 'Document', 'callback_file_selected_test');
    if ($this->form_validation->run() == FALSE) {
         //error
     }
    else{
           // success       
      }
function file_selected_test(){
    $this->form_validation->set_message('file_selected_test', 'Please select file.');
    if (empty($_FILES['userfile']['name'])) {
            return false;
        }else{
            return true;
        }
}

您可以通过覆盖CI_Form_Validation 的Run函数来解决此问题

在扩展CI_Form_Validation的类中复制此函数。

此函数将覆盖父类函数。在这里我只添加了一个额外的检查,它可以处理文件也

/**
 * Run the Validator
 *
 * This function does all the work.
 *
 * @access  public
 * @return  bool
 */
function run($group = '') {
    // Do we even have any data to process?  Mm?
    if (count($_POST) == 0) {
        return FALSE;
    }
    // Does the _field_data array containing the validation rules exist?
    // If not, we look to see if they were assigned via a config file
    if (count($this->_field_data) == 0) {
        // No validation rules?  We're done...
        if (count($this->_config_rules) == 0) {
            return FALSE;
        }
        // Is there a validation rule for the particular URI being accessed?
        $uri = ($group == '') ? trim($this->CI->uri->ruri_string(), '/') : $group;
        if ($uri != '' AND isset($this->_config_rules[$uri])) {
            $this->set_rules($this->_config_rules[$uri]);
        } else {
            $this->set_rules($this->_config_rules);
        }
        // We're we able to set the rules correctly?
        if (count($this->_field_data) == 0) {
            log_message('debug', "Unable to find validation rules");
            return FALSE;
        }
    }
    // Load the language file containing error messages
    $this->CI->lang->load('form_validation');
    // Cycle through the rules for each field, match the
    // corresponding $_POST or $_FILES item and test for errors
    foreach ($this->_field_data as $field => $row) {
        // Fetch the data from the corresponding $_POST or $_FILES array and cache it in the _field_data array.
        // Depending on whether the field name is an array or a string will determine where we get it from.
        if ($row['is_array'] == TRUE) {
            if (isset($_FILES[$field])) {
                $this->_field_data[$field]['postdata'] = $this->_reduce_array($_FILES, $row['keys']);
            } else {
                $this->_field_data[$field]['postdata'] = $this->_reduce_array($_POST, $row['keys']);
            }
        } else {
            if (isset($_POST[$field]) AND $_POST[$field] != "") {
                $this->_field_data[$field]['postdata'] = $_POST[$field];
            } else if (isset($_FILES[$field]) AND $_FILES[$field] != "") {
                $this->_field_data[$field]['postdata'] = $_FILES[$field];
            }
        }
        $this->_execute($row, explode('|', $row['rules']), $this->_field_data[$field]['postdata']);
    }
    // Did we end up with any errors?
    $total_errors = count($this->_error_array);
    if ($total_errors > 0) {
        $this->_safe_form_data = TRUE;
    }
    // Now we need to re-set the POST data with the new, processed data
    $this->_reset_post_array();
    // No errors, validation passes!
    if ($total_errors == 0) {
        return TRUE;
    }
    // Validation fails
    return FALSE;
}
  1. 设置一个规则来检查文件名(如果表单是多部分的)

    $this->form_validation->set_rules('upload_file[name]', 'Upload file', 'required', 'No upload image :(');

  2. 按如下方式覆盖$_POST阵列:

    $_POST['upload_file'] = $_FILES['upload_file']

  3. 然后做:

    $this->form_validation->run()