File Uploading in CodeIgniter 4 Tutorial

In this tutorial, you will learn how the Simple Way of Uploading Files using PHP CodeIgniter. CodeIgniter is one of the popular PHP frameworks that make the developer jobs easier. The goal of this tutorial is to provide the new programmers, especially those who are new to CodeIgniter Framework an Idea of how to upload files. Here, I will be providing a simple application source code that demonstrates our goal for the tutorial.

Getting Started

Before we continue to the coding part, kindly download the following so you could also run the demo application on your end.

  • XAMPP
    • This is a virtual server that allows your local machine to run our PHP Scripts. You can also use other similar software.
  • CodeIgniter
    • Since this tutorial uses the CodeIgniter Framework, you must download it.

The demo application source code I will be providing only uses CDNs for loading the Bootstrap Framework Dependencies. Bootstrap Framework is a CSS (Cascading Style Sheet) that helps the developer to build an application with a good and pleasant user design or user interface to give end-users a better experience while using the application. You must connect to the internet so the CDNs will work and so the system design.

Creating the Database

  1. Open your XAMPP's Control Panel and start the Apache and the MySQL Server.
  2. Open a new tab on your browser and browse http://localhost/phpmyadmin.
  3. Create a new database naming "file_upload_db"
  4. Then, navigate your page to the SQL page and copy/paste the MySQL Script below. The script will create a new table in your database with the columns needed on the app.

The database will serve as the storage of the file details that the users will upload to the application.

App Configuration

Open the App >> Config >> App.php file in your text editor and configure it the same as the script below. In my case, I named my source code folder as ci4_file_upload which you can find in the $baseURL variable. The script below is not the full script of this file. It only shows the part where changes need to be done on your end for this tutorial.

  1.  
  2. <?php
  3.  
  4. namespace Config;
  5.  
  6. use CodeIgniter\Config\BaseConfig;
  7. use CodeIgniter\Session\Handlers\FileHandler;
  8.  
  9. class App extends BaseConfig
  10. {
  11.     /**
  12.      * --------------------------------------------------------------------------
  13.      * Base Site URL
  14.      * --------------------------------------------------------------------------
  15.      *
  16.      * URL to your CodeIgniter root. Typically this will be your base URL,
  17.      * WITH a trailing slash:
  18.      *
  19.      *    http://example.com/
  20.      *
  21.      * If this is not set then CodeIgniter will try guess the protocol, domain
  22.      * and path to your installation. However, you should always configure this
  23.      * explicitly and never rely on auto-guessing, especially in production
  24.      * environments.
  25.      *
  26.      * @var string
  27.      */
  28.     public $baseURL = 'http://localhost/ci4_file_upload/public/';
  29.  
  30.     /**
  31.      * --------------------------------------------------------------------------
  32.      * Index File
  33.      * --------------------------------------------------------------------------
  34.      *
  35.      * Typically this will be your index.php file unless you've renamed it to
  36.      * something else. If you are using mod_rewrite to remove the page set this
  37.      * variable so that it is blank.
  38.      *
  39.      * @var string
  40.      */
  41.     public $indexPage = '';

Configuring the Route

On your App >> Config directory, you will find a PHP file named Routes.php. Open the file on your text editor and configure it like the script below. This will allow us to browse the part or pages on the application using the specific segments or URLs.

  1.  
  2. <?php
  3.  
  4. namespace Config;
  5.  
  6. // Create a new instance of our RouteCollection class.
  7. $routes = Services::routes();
  8.  
  9. // Load the system's routing file first, so that the app and ENVIRONMENT
  10. // can override as needed.
  11. if (is_file(SYSTEMPATH . 'Config/Routes.php')) {
  12.     require SYSTEMPATH . 'Config/Routes.php';
  13. }
  14.  
  15. /*
  16.  * --------------------------------------------------------------------
  17.  * Router Setup
  18.  * --------------------------------------------------------------------
  19.  */
  20. $routes->setDefaultNamespace('App\Controllers');
  21. $routes->setDefaultController('Main');
  22. $routes->setDefaultMethod('index');
  23. $routes->setTranslateURIDashes(false);
  24. $routes->set404Override();
  25. // The Auto Routing (Legacy) is very dangerous. It is easy to create vulnerable apps
  26. // where controller filters or CSRF protection are bypassed.
  27. // If you don't want to define all routes, please use the Auto Routing (Improved).
  28. // Set `$autoRoutesImproved` to true in `app/Config/Feature.php` and set the following to true.
  29. //$routes->setAutoRoute(false);
  30.  
  31. /*
  32.  * --------------------------------------------------------------------
  33.  * Route Definitions
  34.  * --------------------------------------------------------------------
  35.  */
  36.  
  37. // We get a performance increase by specifying the default
  38. // route since we don't have to scan directories.
  39. $routes->get('/', 'Main::index');
  40. $routes->post('file/upload', 'Main::upload');
  41.  
  42. /*
  43.  * --------------------------------------------------------------------
  44.  * Additional Routing
  45.  * --------------------------------------------------------------------
  46.  *
  47.  * There will often be times that you need additional routing and you
  48.  * need it to be able to override any defaults in this file. Environment
  49.  * based routes is one such time. require() additional route files here
  50.  * to make that happen.
  51.  *
  52.  * You will have access to the $routes object within that file without
  53.  * needing to reload it.
  54.  */
  55. if (is_file(APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php')) {
  56.     require APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php';
  57. }

Creating the Model

On your App >> models directory, create a new PHP file named File.php. This file contains the script and variables for our application to manage data in our database file_upload table. Write the following script below and save the file.

  1. <?php
  2.  
  3. namespace App\Models;
  4.  
  5. use CodeIgniter\Model;
  6.  
  7. class File extends Model
  8. {
  9.     protected $DBGroup          = 'default';
  10.     protected $table            = 'files';
  11.     protected $primaryKey       = 'id';
  12.     protected $useAutoIncrement = true;
  13.     protected $insertID         = 0;
  14.     protected $returnType       = 'array';
  15.     protected $useSoftDeletes   = false;
  16.     protected $protectFields    = true;
  17.     protected $allowedFields    = ['label','path'];
  18.  
  19.     // Dates
  20.     protected $useTimestamps = false;
  21.     protected $dateFormat    = 'datetime';
  22.     protected $createdField  = 'created_at';
  23.     protected $updatedField  = 'updated_at';
  24.     protected $deletedField  = 'deleted_at';
  25.  
  26.     // Validation
  27.     protected $validationRules      = [];
  28.     protected $validationMessages   = [];
  29.     protected $skipValidation       = false;
  30.     protected $cleanValidationRules = true;
  31.  
  32.     // Callbacks
  33.     protected $allowCallbacks = true;
  34.     protected $beforeInsert   = [];
  35.     protected $afterInsert    = [];
  36.     protected $beforeUpdate   = [];
  37.     protected $afterUpdate    = [];
  38.     protected $beforeFind     = [];
  39.     protected $afterFind      = [];
  40.     protected $beforeDelete   = [];
  41.     protected $afterDelete    = [];
  42. }

Creating the Controller

On your App >> Controllers directory, create a new PHP file naming Main.php. This file contains the PHP codes that display our pages and process our uploaded data. Write the following script on your end too.

  1. <?php
  2.  
  3. namespace App\Controllers;
  4.  
  5. use App\Controllers\BaseController;
  6. use App\Models\File;
  7.  
  8. class Main extends BaseController
  9. {
  10.     public function __construct(){
  11.         $this->db = db_connect();
  12.         $this->model= new File;
  13.         $this->session = session();
  14.         $this->request =  \Config\Services::request();
  15.         $this->data['session']= $this->session ;
  16.         $this->data['request'] = $this->request ;
  17.         $this->data['uploads']= $this->model->findAll();
  18.     }
  19.     public function index(){
  20.         return view('home', $this->data);
  21.     }
  22.  
  23.     public function upload(){
  24.         if(!is_dir('./uploads/'))
  25.         mkdir('./uploads/');
  26.         $label = $this->request->getPost('label');
  27.         $file = $this->request->getFile('file');
  28.         $fname = $file->getRandomName();
  29.         while(true){
  30.             $check = $this->model->where("path", "uploads/{$fname}")->countAllResults();
  31.             if($check > 0){
  32.                 $fname = $file->getRandomName();
  33.             }else{
  34.                 break;
  35.             }
  36.         }
  37.         if($file->move("uploads/", $fname)){
  38.             $this->model->save([
  39.                 "label" =>$this->db->escapeString($label),
  40.                 "path" => "uploads/".$fname
  41.             ]);
  42.             $this->session->setFlashdata('main_success',"New File Uploaded successfully.");
  43.             return redirect()->to('/');
  44.         }else{
  45.             $this->session->setFlashdata('main_success',"File Upload failed.");
  46.         }
  47.             return view('home', $this->data);
  48.     }
  49. }

Creating the View

Lastly, create a new file naming home.php on your App >> Views directory. This file contains the HTML and PHP Scripts of our application interface. The script contains included CDNs, our form panel elements, and the display panel for the list of uploaded files.

  1. <!DOCTYPE html>
  2. <html lang="en">
  3.     <meta charset="UTF-8">
  4.     <meta http-equiv="X-UA-Compatible" content="IE=edge">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>CodeIgniter File Upload</title>
  7.  
  8.     <!-- Font Awesome -->
  9.     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" />
  10.     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" integrity="sha512-nMNlpuaDPrqlEls3IX/Q56H36qvBASwb3ipuo3MxeWbsQB1881ox0cRv7UPTgBlriqoynt35KjEwgGUeUXIPnw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
  11.  
  12.     <!-- Bootstrap -->
  13.     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
  14.  
  15.     <!-- Font Awesome -->
  16.     <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/js/all.min.js" integrity="sha512-6PM0qYu5KExuNcKt5bURAoT6KCThUmHRewN3zUFNaoI6Di7XJPTMoT6K0nsagZKk2OB4L7E3q1uQKHNHd4stIQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  17.  
  18.     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  19.     <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
  20.  
  21.     <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js" integrity="sha512-2ImtlRlf2VVmiGZsjm9bEyhjGW4dU7B6TNwh/hx/iSByxNENtj3WVE6o/9Lj4TJeVXPi4bnOIMXFIJJAeufa0A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  22.  
  23.     <style>
  24.         html, body{
  25.             height:100%;
  26.             width:100%;
  27.         }
  28.     </style>
  29. </head>
  30. <body class="bg-dark bg-gradient bg-opacity-25">
  31.     <div class="container py-4">
  32.             <h1 class="text-center fw-bold">File Uploading in CodeIgniter 4</h1>
  33.             <hr>
  34.             <?php if($session->getFlashdata('main_error')): ?>
  35.                 <div class="alert alert-danger rounded-0">
  36.                     <?= $session->getFlashdata('main_error') ?>
  37.                 </div>
  38.             <?php endif; ?>
  39.             <?php if($session->getFlashdata('main_success')): ?>
  40.                 <div class="alert alert-success rounded-0">
  41.                     <?= $session->getFlashdata('main_success') ?>
  42.                 </div>
  43.             <?php endif; ?>
  44.             <div class="clear-fix py-2"></div>
  45.             <div class="row">
  46.                 <div class="col-lg-4 col-md-6 col-sm-12 col-xs-12">
  47.                     <div class="card rounded-0 shadow">
  48.                         <div class="card-header">
  49.                             <div class="card-title h4 mb-0 fw-bold">Upload File Form</div>
  50.                         </div>
  51.                         <div class="card-body">
  52.                             <div class="container-fluid">
  53.                                 <form action="<?= base_url('file/upload') ?>" method="POST" id="file-upload" enctype="multipart/form-data">
  54.                                     <div class="mb-3">
  55.                                         <label for="label" class="control-label">File Label</label>
  56.                                         <input type="text" name="label" id="label" class="form-control rounded-0">
  57.                                     </div>
  58.                                     <div class="mb-3">
  59.                                         <label for="formFile" class="form-label">File</label>
  60.                                         <input class="form-control rounded-0" name="file" type="file" id="formFile">
  61.                                     </div>
  62.                                 </form>
  63.                             </div>
  64.                         </div>
  65.                         <div class="card-footer text-center">
  66.                             <button class="btn btn-primary btn-sm bg-gradient rounded-0" form="file-upload"><i class="fa fa-save"></i> Save File</button>
  67.                             <button class="btn btn-light border btn-sm bg-gradient rounded-0" type="reset" form="file-upload"><i class="fa fa-times"></i> Reset</button>
  68.                         </div>
  69.                     </div>
  70.                 </div>
  71.                 <div class="col-lg-8 col-md-6 col-sm-12 col-xs-12">
  72.                     <div class="card rounded-0 shadow">
  73.                         <div class="card-header">
  74.                             <div class="card-title h4 mb-0 fw-bolder">Uploaded Files</div>
  75.                         </div>
  76.                         <div class="card-body">
  77.                             <div class="container-fluid">
  78.                                 <table class="table table-striped table-bordered">
  79.                                     <colgroup>
  80.                                         <col width="10%">
  81.                                         <col width="20%">
  82.                                         <col width="50%">
  83.                                         <col width="20%">
  84.                                     </colgroup>
  85.                                     <thead>
  86.                                         <tr class="bg-primary bg-gradient text-light">
  87.                                             <th class="p-1 text-center">#</th>
  88.                                             <th class="p-1 text-center">Label</th>
  89.                                             <th class="p-1 text-center">Path</th>
  90.                                             <th class="p-1 text-center"></th>
  91.                                         </tr>
  92.                                     </thead>
  93.                                     <tbody>
  94.                                         <?php
  95.                                        $i = 1;
  96.                                        foreach($uploads as $row):
  97.                                            $row['fname'] = str_replace("uploads/","", $row['path']);
  98.                                        ?>
  99.                                         <tr>
  100.                                             <td class="px-2 py-1 align-middle text-center"><?= number_format($i++) ?></td>
  101.                                             <td class="px-2 py-1 align-middle"><?= $row['label'] ?></td>
  102.                                             <td class="px-2 py-1 align-middle"><p class="m-0 text-truncate" title="<?= $row['fname'] ?>"><?= $row['fname'] ?></p></td>
  103.                                             <td class="px-2 py-1 align-middle text-center">
  104.                                                 <a href="<?= $row['path'] ?>" class="text-muted text-decoration-none mx-2" target="_blank" title="View File"><i class="fa fa-external-link"></i></a>
  105.                                                 <a href="<?= base_url($row['path']) ?>" class="text-primary fw-bolder text-decoration-none mx-2" target="_blank" title="Download File" download="<?= $row['fname'] ?>"><i class="fa fa-download"></i></a>
  106.                                             </td>
  107.                                         </tr>
  108.                                         <?php endforeach; ?>
  109.                                         <?php if(!isset($uploads) || (isset($uploads) && count($uploads) <= 0)): ?>
  110.                                             <tr>
  111.                                                 <th colspan="4" class="p-1 text-center">No records found</th>
  112.                                             </tr>
  113.                                         <?php endif; ?>
  114.                                     </tbody>
  115.                                 </table>
  116.                             </div>
  117.                         </div>
  118.                     </div>
  119.                 </div>
  120.             </div>
  121.     </div>
  122. </body>
  123. </html>

That's it! You can now test the application on your end. To do that, browse http://localhost/[source_code_folder_name]/public/ in your browser. Check the application if it works and achieves our goal for this tutorial.

DEMO VIDEO

If in any case you'll find or encounter any errors on your end, please review your source code maybe you have missed something or you can also download the working source code I created for this tutorial. The download link is located below this article.

That's the end of this tutorial. I hope this tutorial will help you with what you are looking for and you'll find this useful for your current or future CodeIgniter Project. Explore more on this website for more tutorials and Free Source Codes.

Happy Coding :)

Comments

Thanks! Will test this later.  

Add new comment