Codeigniter Multiple Files Upload

File upload example in Codeigniter 2.1.4. There is file upload class, in Codeigniter, which permits you to upload the file or files. This class also permits you to set various preferences such as destination where the file will be uploaded, restriction on file types, restriction on file size, whether a file name should be encrypted or not, maximum length of the file name etc.

Please feel free to contact if you have any query.

Below are the simple few processes for uploading a file

  • A form with input type file is required so that user can select the file using the browse button
  • When the form is submitted, the file is validated to make sure that the file is uploaded against the preferences you set
  • Once the file is uploaded successfully to the specified destination, the success message is shown
  • The output in the browser

When the upload form is shown to the user

Codeigniter multiple files upload

When user submits without selecting file

Codeigniter multiple files upload

When user selects file(s) and submit the form

Codeigniter multiple files upload

Codeigniter multiple files upload

A typical directory structure will be as shown below. The upload directory contains the uploaded file(s).

Codeigniter multiple files upload

Create the table in the database – table name files

CREATE TABLE `files` (
  `file_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `file_name` varchar(255) COLLATE latin1_general_ci NOT NULL,
  `file_orig_name` varchar(255) COLLATE latin1_general_ci NOT NULL,
  `file_path` varchar(255) COLLATE latin1_general_ci NOT NULL,
  `upload_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`file_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

 

Go to application/config/database.php and change the value as per your database settings

$db['default']['hostname'] = 'localhost';
$db['default']['username'] = 'root';
$db['default']['password'] = '';
$db['default']['database'] = 'ci_post';
$db['default']['dbdriver'] = 'mysql';

 

Go to application/config/autoload.php and change the value as shown below

$autoload['libraries'] = array('database');
$autoload['helper'] = array('url', 'file', 'text', 'form');

 

Create a assets helper file which gives us the URL for different assets like css, js etc. Put it under application/helpers/

<?php
 
if (!defined('BASEPATH'))
    exit('No direct script access allowed');
 
function assets_url() {
    return base_url();
}
 
/* End of file assets_helper.php */
/* Location: ./application/helpers/assets_helper.php */

 

Create the view – upload form

As shown previously in the directory structure image, you have to create a form called uploadfiles.php under application/views/ folder. This below file upload form expects at least one file must be selected using the browse button. You will also notice that once you select at least one file, a link Attach another file gets appeared for adding a new browse button for selecting another file.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Upload Multiple File(s)</title>
        <style type="text/css">
            body {
                background-color: #fff;
                margin: 40px;
                font: 13px/20px normal Helvetica, Arial, sans-serif;
                color: #4F5155;
            }
            #body{
                margin: 0 15px 0 15px;
            }
            #container{
                margin: 10px;
                border: 1px solid #D0D0D0;
                -webkit-box-shadow: 0 0 8px #D0D0D0;
            }
            .error {
                color: #E13300;
            }
            .info {
                color: gold;
            }
            .success {
                color: darkgreen;
            }
        </style>
        <script src="<?php echo assets_url(); ?>assets/js/jquery-1.9.1.min.js"></script>
    </head>
    <body>
        <div class="message_box">
            <?php
            if (isset($success) && strlen($success)) {
                echo '<div class="success">';
                echo '<p>' . $success . '</p>';
                echo '</div>';
            }

            if (isset($errors) && strlen($errors)) {
                echo '<div class="error">';
                echo '<p>' . $errors . '</p>';
                echo '</div>';
            }

            if (validation_errors()) {
                echo validation_errors('<div class="error">', '</div>');
            }
            ?>
        </div>
        <div>
            <?php
            echo form_open_multipart($this->uri->uri_string(), array('id' => 'upload-file-form'));
            ?>
            <fieldset>
                <legend>Upload Multiple File(s)</legend>
                <section>
                    <label>Browse a file</label>
                    <label>
                        <input type="file" name="upload_file1" id="upload_file1" readonly="true"/>
                    </label>
                    <div id="moreImageUpload"></div>
                    <div style="clear:both;"></div>
                    <div id="moreImageUploadLink" style="display:none;margin-left: 10px;">
                        <a href="javascript:void(0);" id="attachMore">Attach another file</a>
                    </div>
                </section>
            </fieldset>
            <footer>
                <input type="submit" name="file_upload" value="Upload"/>
            </footer>
            <?php
            echo form_close();
            ?>
        </div>        
    </body>
</html>
<script type="text/javascript">
    $(document).ready(function() {
        $("input[id^='upload_file']").each(function() {
            var id = parseInt(this.id.replace("upload_file", ""));
            $("#upload_file" + id).change(function() {
                if ($("#upload_file" + id).val() !== "") {
                    $("#moreImageUploadLink").show();
                }
            });
        });
    });
</script>
<script type="text/javascript">
    $(document).ready(function() {
        var upload_number = 2;
        $('#attachMore').click(function() {
            //add more file
            var moreUploadTag = '';
            moreUploadTag += '<div class="element"><label for="upload_file"' + upload_number + '>Upload File ' + upload_number + '</label>';
            moreUploadTag += '<input type="file" id="upload_file' + upload_number + '" name="upload_file' + upload_number + '"/>';
            moreUploadTag += '&nbsp;<a href="javascript:del_file(' + upload_number + ')" style="cursor:pointer;" onclick="return confirm(\"Are you really want to delete ?\")">Delete ' + upload_number + '</a></div>';
            $('<dl id="delete_file' + upload_number + '">' + moreUploadTag + '</dl>').fadeIn('slow').appendTo('#moreImageUpload');
            upload_number++;
        });
    });
</script>
<script type="text/javascript">
    function del_file(eleId) {
        var ele = document.getElementById("delete_file" + eleId);
        ele.parentNode.removeChild(ele);
    }
</script>

 

In the above form I have used Codeigniter’s form helper tags. Also notice when we need to upload a file or files we have to use the enctype=”multipart/form-data” and hence we have used form_open_multipart(). If there is no need to upload a file then we can use only form_open(). We have passed some attributes, in form_open_multipart(), which will be added in the html’s form tag. We have also some other variables like $errors, $success which will show errors and success messages respectively. We have Codeigniter’s built-in validation_errors() function which will show also error messages.

Download jquery file jquery-1.9.1.min

File upload Controller

We have already default controller called uploadfiles.php under application/controllers/. If you want you can also create your own controller. You can find the explanations in the comment for important statements.

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

/**
 *
 * @author https://www.roytuts.com
 */
class UploadFiles extends CI_Controller {

    private $error;
    private $success;

    function __construct() {
        parent::__construct();
        $this->load->library('form_validation');
        $this->load->model('file_model', 'file');
    }

    private function handle_error($err) {
        $this->error .= $err . "\r\n";
    }

    private function handle_success($succ) {
        $this->success .= $succ . "\r\n";
    }

    function index() {
        if ($this->input->post('file_upload')) {
            //file upload destination
            $dir_path = './upload/';
            $config['upload_path'] = $dir_path;
            $config['allowed_types'] = '*';
            $config['max_size'] = '0';
            $config['max_filename'] = '255';
            $config['encrypt_name'] = TRUE;

            //upload file
            $i = 0;
            $files = array();
            $is_file_error = FALSE;

            if ($_FILES['upload_file1']['size'] <= 0) {
                $this->handle_error('Select at least one file.');
            } else {
                foreach ($_FILES as $key => $value) {
                    if (!empty($value['name'])) {
                        $this->load->library('upload', $config);
                        if (!$this->upload->do_upload($key)) {
                            $this->handle_error($this->upload->display_errors());
                            $is_file_error = TRUE;
                        } else {
                            $files[$i] = $this->upload->data();
                            ++$i;
                        }
                    }
                }
            }

            // There were errors, we have to delete the uploaded files
            if ($is_file_error && $files) {
                for ($i = 0; $i < count($files); $i++) {
                    $file = $dir_path . $files[$i]['file_name'];
                    if (file_exists($file)) {
                        unlink($file);
                    }
                }
            }

            if (!$is_file_error && $files) {
                $resp = $this->file->save_files_info($files);
                if ($resp === TRUE) {
                    $this->handle_success('File(s) was/were successfully uploaded.');
                } else {
                    for ($i = 0; $i < count($files); $i++) {
                        $file = $dir_path . $files[$i]['file_name'];
                        if (file_exists($file)) {
                            unlink($file);
                        }
                    }
                    $this->handle_error('Error while saving file info to Database.');
                }
            }
        }
        $data['errors'] = $this->error;
        $data['success'] = $this->success;
        $this->load->view('uploadfiles', $data);
    }

}

/* End of file uploadfiles.php */
/* Location: ./application/controllers/uploadfiles.php */

 

The Model

This model class is responsible for interacting with the database and save the file info to the database.

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

/**
 *
 * @author https://www.roytuts.com
 */
class File_Model extends CI_Model {

    //table name
    private $file = 'files';   // files    
    
    function save_files_info($files) {
        //start db traction
        $this->db->trans_start();
        //file data
        $file_data = array();
        foreach ($files as $file) {
            $file_data[] = array(
                'file_name' => $file['file_name'],
                'file_orig_name' => $file['orig_name'],
                'file_path' => $file['full_path'],
                'upload_date' => date('Y-m-d H:i:s')
            );
        }
        //insert file data
        $this->db->insert_batch($this->file, $file_data);
        //complete the transaction
        $this->db->trans_complete();
        //check transaction status
        if ($this->db->trans_status() === FALSE) {
            foreach ($files as $file) {
                $file_path = $file['full_path'];
                //delete the file from destination
                if (file_exists($file_path)) {
                    unlink($file_path);
                }
            }
            //rollback transaction
            $this->db->trans_rollback();
            return FALSE;
        } else {
            //commit the transaction
            $this->db->trans_commit();
            return TRUE;
        }
    }

}

 

For more information on file upload you can have a look at this http://ellislab.com/codeigniter/user-guide/libraries/file_uploading.html

That’s all. Thanks for your reading. Please do not forget to leave a comment.

Codeigniter Multiple Files Upload

14 thoughts on “Codeigniter Multiple Files Upload

  1. thanks a lot for your post
    if I want to add one input text, example : description.
    how about the model and the controller ?

    1. in the same way as other input fields are added to the form and submitted to the controller. just add another input field and get the value of the input field in the controller and then pass the value to the model.

  2. Why create and use the `assets_url()` helper function? In this article it is completely pointless since all it does is returns base_url(). It is adding an extra trip to memory to consume the assets_url() function and for no reason when instead you could avoid it and use base_url() in your views and not /assets. If you want a decent replacement for the assets_url() function, I would suggest using the following alternative instead.

    In assets_helper.php (>=PHP7):

    // If the function does not exist, let’s create it!
    if (!function_exists(‘assets_url’)) {
    /**
    * A syntactic sugar function to help load assets.
    *
    * @param string|null $file The asset file to load
    * @param string $path The path for the asset
    *
    * @return string The assets full `path`
    */
    function assetsUrl(string $file = null, string $path = ‘assets’): string
    {
    return base_url($path . ‘/’ . $file);
    }
    }

    The function above proves much more useful for accessing assets relative to your public directory/FCPATH.

    Other than this little “mistake” in your code, everything else is pretty decent. Thank you for the article.

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top