Thursday, December 1, 2016

How to Upload File in CodeIgniter

File upload is one of the most common requiremets for most web applications. We could either implement this with native PHP or just use the CodeIgniter's way. Well, of course, we'll be going the CodeIgniter's way. CodeIgniter framework provides a descent and efficient way of doing such a thing. CodeIgniter's File Upload library is easy and simple. In this tutorial, we'll be creating a basic file upload feature, which you could then extend for your project.

At the end of this tutorial, you would have an interface like the following images.

Step 1. Create a Controller

First of all, we need a controller to send our request. We need to access an interface wherein we have a form and a submit button but before we create that view we need to have a controller to map the view file. Go ahead and create a controller name "Upload.php" and place it under "application/controllers".
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Upload extends CI_Controller {

    public function __construct()
    {
        parent::__construct();
    }
    public function index()
    {
        $this->load->view('upload');
    }
}
The view "upload" has not been created yet.

Step 2. Create a view

The view "upload" is where we insert our form for submitting our file. Go ahead and create a view name "upload" in "application/views" folder and paste the following code.
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CodeIgniter Contact Form Example</title>
    <!--load bootstrap css-->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css" integrity="sha384-AysaV+vQoT3kOAXZkl02PThvDr8HYKPZhNT5h/CXfBThSRXQ6jW5DO2ekP5ViFdi" crossorigin="anonymous">

    <style>
        .container{
            padding:5%;
        }
        .modal .modal-body{
            display: flex;
            align-items: center;
            justify-content: center;
            margin: 57px 0px 57px 0px;
        }
        .modal .modal-title{
            text-align:center;
        }
        .custom-file-control{
            position: absolute;
            top: 0;
            right: 0;
            left: 0;
            z-index: 5;
            height: 2.5rem;
            padding: .5rem 1rem;
            line-height: 1.5;
            color: #555;
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
            background-color: #fff;
            border: 1px solid #ddd;
            border-radius: .25rem;
        }
        .custom-file-control::before{
            content:"Browse";
            position: absolute;
            top: -1px;
            right: -1px;
            bottom: -1px;
            z-index: 6;
            display: block;
            height: 2.5rem;
            padding: .5rem 1rem;
            line-height: 1.5;
            color: #555;
            background-color: #eee;
            border: 1px solid #ddd;
            border-radius: 0 .25rem .25rem 0;
        }
        .custom-file-control::after{
            content:attr(data-attr);
        }
        .flex-center-cont{
            display: flex;
            align-items: center;
            justify-content: center;
            flex-direction: column;
        }
    </style>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script>var base_url = "<?=base_url();?>";</script>
</head>
<body>
    <div class="container">
        <div class="row flex-items-xs-center flex-center-cont">
            <div class="col-xs-4">
                <form action="#" id="upload-form">
                    <div class="form-group">
                        <label class="custom-file col-xs-12">
                            <input type="file" id="file" class="custom-file-input" name="myfile" placeholder="Choose file">
                            <span class="custom-file-control" data-attr="Choose file..."></span>
                        </label>
                    </div>
                    <div class="form-group">
                        <input name="submit" type="submit" class="btn btn-lg btn-outline-success btn-block" value="Submit" />
                    </div>
                </form>
            </div>
        </div>
    </div>
    <script src="https://www.atlasestateagents.co.uk/javascript/tether.min.js"></script><!-- Tether for Bootstrap -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/js/bootstrap.min.js" integrity="sha384-BLiI7JTZm+JWlgKa0M0kGRpJbF2J8q+qreVrKBC47e3K6BW78kGLrCkeRX6I9RoK" crossorigin="anonymous"></script>
    <script>
        $(function(){
            $('input[name="myfile"]').on('change',function(e){
                var filename = document.getElementById("file").files[0].name;
                $(this).next().attr('data-attr',filename);
                $('input[name="myfile"]').closest('.form-group.has-error').removeClass('has-error').find('span.text-danger').remove();
            })
            $('#upload-form').on('submit',function(e){
                e.preventDefault();
                var $btn = $(this).find('input[type="submit"]');
                var formdata = new FormData(this);
                $.ajax({
                    url: base_url+'upload/do_upload',
                    type: 'POST',
                    dataType: 'JSON',
                    data:formdata,
                    cache:false,
                    contentType: false,
                    processData: false,
                    beforeSend:function(){
                        $btn.button('loading');
                    },
                    success:function(response){
                        $('.form-group.has-error').removeClass('has-error').find('span.text-danger').remove();
                        switch(response.status){
                            case 'form-incomplete':
                                $.each(response.errors, function(key,val){
                                    if(val.error!=''){
                                        $(val.field).closest('.form-group').addClass('has-error').append(val.error);
                                    }
                                })
                            break;
                            case 'success':
                                // window.location.reload(true);
                                var data = 
                                    "<div class='col-xs'>"+
                                        "<table class='table'>"+
                                             "<thead class='thead-inverse'>"+
                                                "<tr>"+
                                                    "<th>"+
                                                        "Key"+
                                                    "</th>"+
                                                    "<th>"+
                                                        "Value"+
                                                    "</th>"+
                                                "</tr>"+
                                             "</thead>";
                                $.each(response.data,function(key,val){
                                    data+=
                                    "<tr>"+
                                        "<td>"+
                                            key+
                                        "</td>"+
                                        "<td>"+
                                            val+
                                        "</td>"+
                                    "<tr>";
                                })
                                data+="</table></div>";
                                $(".flex-center-cont").append(data);
                            break;
                            case 'error':
                                $('input[name="myfile"]').closest('.form-group').addClass('has-error').append("<span class='text-danger'>"+response.errors+"</span>");
                                console.log(response.message);
                            break;
                        }
                    },
                    error: function(jqXHR,textStatus,error){
                        console.log('Unable to send request!');
                    }
                }).always(function(){
                    $btn.button('reset');
                });
            })
        })
    </script>
</body>
</html>

Step 3. Add a Function

The code above contain our css and javascript files, you should, however, separate these to an external files in your real project. When user select a file to upload then click on submit button, the form will be submitted to our "Upload" controller through ajax. We don't have "do_upload" function in our controller yet. Go ahead and create that function with the following code.
public function do_upload()
    {
        if(!$this->input->is_ajax_request()){
            show_404();
        }
        try{
            $config=  array(
                'upload_path'      => "./uploads/files/",
                'allowed_types'   => "gif|jpg|png|jpeg|pdf|doc|xml",
                'overwrite'       => TRUE,
                'max_size'        => "1000KB",
                'max_height'      => "768",
                'max_width'       => "1024"  
            );
            if(!is_dir($config['upload_path'])){
                mkdir($config['upload_path'], 0777, TRUE);
            }
            
            $this->load->library('upload', $config);
            $response = false;
            if($this->upload->do_upload('myfile'))
            {
                $response['status'] = 'success';
                $response['message'] = 'Successfully uploaded';
                $response['data'] = $this->upload->data();
            }
            else
            {
                $response['status'] = 'error';
                $response['message'] = 'Failed to upload file';
                $response['errors'] = $this->upload->display_errors();
            }
        }
        catch(Exception $e){
            $response['status']='error';
            $response['message']='Something went wrong while trying to communicate with the server.';
        }
        echo json_encode($response);
    }

What our controller does is it determines whether the call is from an ajax request. If it is, then continue the process, otherwise, redirect to 404 page. One thing you'll notice is the config variable. Basically, it is an associative array that contains our preferred settings for uploading file such as the options we have above. We're only allowing files which have maximum file size of 1000kb, an image file with maximum height of 768 pixels, and a maximum width of 1024 pixels. If you don't wan't to limit your file size, you could set it to 0, same goes to max_height and max_width options.

We then check if the path we set as the upload path exist or not. If the directory doesn't exist, we'll create that directory with a 0777 permission which basically means we're giving it a read, write, and execute permission. Afterwards, we passed our config variable to our upload class which overwrites the default CI configuration. To upload the file, we passed the input variable name to "do_upload()" function which returns a Boolean value.

 To get the properties of the uploaded file, we run "upload->data()". When things don't workout as expected, you could display the error messages to determine where you messed up. You could do this by running the code "upload->display_errors()". Whether the file has been uploaded or not, we are returning some data in json format which we then manipulate in our ajax success callback.
That's it, I hope this simple tutorial will help you get started on your CodeIgniter project.

1 comment:

  1. Hello World !
    Good Day !

    Keep you services updated & reliable with my stuff
    Huge stuff of Tools, E-boooks, Tutorials, Scripting, Viruses, Spying e.t.c

    See Me On
    I C Q :> 752822040
    Tele-Gram :> @killhacks

    Many other stuff like
    SSN/DL
    ID's
    CC CVV
    DUMPS
    Combos/I.P's/Proxies
    You can get from my collections :-)

    No one TEACH you
    No one GUIDE you
    No one BOOST you
    But I'm always here for you

    Hit me up for you desired stuff
    I C Q here :> 752 822 040
    Tele-Gram here :> @killhacks

    %Waiting for you guys%

    ReplyDelete