如何使用CodeIgniter的文件上传类验证和“只读”文件?

时间:2018-03-19 02:47:54

标签: php codeigniter

我正在尝试使用CodeIgniter上传Excel文件。我想要做的就是只读取文件,而不是在配置中需要的上传路径中移动/上传文件。

是的,我可以使用本机PHP的$_FILES超全局变量。但是,我喜欢使用该库,因为它为我的应用程序提供了额外的安全性。

那么..如何使用CI的文件上传类上传文件而不上传到我的服务器?

$config['upload_path'] = './public/uploads/';
$config['allowed_types'] = 'xlsx|xls';

$this->load->library('upload', $config);

if(!$this->upload->do_upload('userfile'))
{
    $this->output->set_output(array('result' => FALSE, 'message' => $this->upload->display_errors()))->_display();
    exit(1);
}
else
{
    $data = $this->upload->data();

    // Let the model do his work!
    $this->load->model('Userlist_Model');
    $result = $this->Userlist_Model->extract_list($data);

    $this->output->set_output($result)->_display();
}

1 个答案:

答案 0 :(得分:0)

这是我的解决方案:只需在libraries文件夹中创建MY_Upload即可扩展Upload.php(CI_Upload)。复制do_upload()方法,然后删除上传开始的部分:

<强> MY_Upload.php

class MY_Upload extends CI_Upload
{
    public function validate_file($field = 'userfile')
    {
        // Is $_FILES[$field] set? If not, no reason to continue.
        if (isset($_FILES[$field]))
        {
            $_file = $_FILES[$field];
        }
        // Does the field name contain array notation?
        elseif (($c = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $field, $matches)) > 1)
        {
            $_file = $_FILES;
            for ($i = 0; $i < $c; $i++)
            {
                // We can't track numeric iterations, only full field names are accepted
                if (($field = trim($matches[0][$i], '[]')) === '' OR ! isset($_file[$field]))
                {
                    $_file = NULL;
                    break;
                }

                $_file = $_file[$field];
            }
        }

        if ( ! isset($_file))
        {
            $this->set_error('upload_no_file_selected', 'debug');
            return FALSE;
        }

        // Is the upload path valid?
        if ( ! $this->validate_upload_path())
        {
            // errors will already be set by validate_upload_path() so just return FALSE
            return FALSE;
        }

        // Was the file able to be uploaded? If not, determine the reason why.
        if ( ! is_uploaded_file($_file['tmp_name']))
        {
            $error = isset($_file['error']) ? $_file['error'] : 4;

            switch ($error)
            {
                case UPLOAD_ERR_INI_SIZE:
                    $this->set_error('upload_file_exceeds_limit', 'info');
                    break;
                case UPLOAD_ERR_FORM_SIZE:
                    $this->set_error('upload_file_exceeds_form_limit', 'info');
                    break;
                case UPLOAD_ERR_PARTIAL:
                    $this->set_error('upload_file_partial', 'debug');
                    break;
                case UPLOAD_ERR_NO_FILE:
                    $this->set_error('upload_no_file_selected', 'debug');
                    break;
                case UPLOAD_ERR_NO_TMP_DIR:
                    $this->set_error('upload_no_temp_directory', 'error');
                    break;
                case UPLOAD_ERR_CANT_WRITE:
                    $this->set_error('upload_unable_to_write_file', 'error');
                    break;
                case UPLOAD_ERR_EXTENSION:
                    $this->set_error('upload_stopped_by_extension', 'debug');
                    break;
                default:
                    $this->set_error('upload_no_file_selected', 'debug');
                    break;
            }

            return FALSE;
        }

        // Set the uploaded data as class variables
        $this->file_temp = $_file['tmp_name'];
        $this->file_size = $_file['size'];

        // Skip MIME type detection?
        if ($this->detect_mime !== FALSE)
        {
            $this->_file_mime_type($_file);
        }

        $this->file_type = preg_replace('/^(.+?);.*$/', '\\1', $this->file_type);
        $this->file_type = strtolower(trim(stripslashes($this->file_type), '"'));
        $this->file_name = $this->_prep_filename($_file['name']);
        $this->file_ext  = $this->get_extension($this->file_name);
        $this->client_name = $this->file_name;

        // Is the file type allowed to be uploaded?
        if ( ! $this->is_allowed_filetype())
        {
            $this->set_error('upload_invalid_filetype', 'debug');
            return FALSE;
        }

        // if we're overriding, let's now make sure the new name and type is allowed
        if ($this->_file_name_override !== '')
        {
            $this->file_name = $this->_prep_filename($this->_file_name_override);

            // If no extension was provided in the file_name config item, use the uploaded one
            if (strpos($this->_file_name_override, '.') === FALSE)
            {
                $this->file_name .= $this->file_ext;
            }
            else
            {
                // An extension was provided, let's have it!
                $this->file_ext = $this->get_extension($this->_file_name_override);
            }

            if ( ! $this->is_allowed_filetype(TRUE))
            {
                $this->set_error('upload_invalid_filetype', 'debug');
                return FALSE;
            }
        }

        // Convert the file size to kilobytes
        if ($this->file_size > 0)
        {
            $this->file_size = round($this->file_size/1024, 2);
        }

        // Is the file size within the allowed maximum?
        if ( ! $this->is_allowed_filesize())
        {
            $this->set_error('upload_invalid_filesize', 'info');
            return FALSE;
        }

        // Are the image dimensions within the allowed size?
        // Note: This can fail if the server has an open_basedir restriction.
        if ( ! $this->is_allowed_dimensions())
        {
            $this->set_error('upload_invalid_dimensions', 'info');
            return FALSE;
        }

        // Sanitize the file name for security
        $this->file_name = $this->_CI->security->sanitize_filename($this->file_name);

        // Truncate the file name if it's too long
        if ($this->max_filename > 0)
        {
            $this->file_name = $this->limit_filename_length($this->file_name, $this->max_filename);
        }

        // Remove white spaces in the name
        if ($this->remove_spaces === TRUE)
        {
            $this->file_name = preg_replace('/\s+/', '_', $this->file_name);
        }

        if ($this->file_ext_tolower && ($ext_length = strlen($this->file_ext)))
        {
            // file_ext was previously lower-cased by a get_extension() call
            $this->file_name = substr($this->file_name, 0, -$ext_length).$this->file_ext;
        }

        /*
         * Validate the file name
         * This function appends an number onto the end of
         * the file if one with the same name already exists.
         * If it returns false there was a problem.
         */
        $this->orig_name = $this->file_name;
        if (FALSE === ($this->file_name = $this->set_filename($this->upload_path, $this->file_name)))
        {
            return FALSE;
        }

        /*
         * Run the file through the XSS hacking filter
         * This helps prevent malicious code from being
         * embedded within a file. Scripts can easily
         * be disguised as images or other file types.
         */
        if ($this->xss_clean && $this->do_xss_clean() === FALSE)
        {
            $this->set_error('upload_unable_to_write_file', 'error');
            return FALSE;
        }

        /*
         * Set the finalized image dimensions
         * This sets the image width/height (assuming the
         * file was an image). We use this information
         * in the "data" function.
         */
        $this->set_image_properties($this->upload_path.$this->file_name);

        // Return true if the file passed the validation
        return TRUE;
    }
}