Codeigniter 4 Ajax Image upload using MySQL
Uploading Images from client to server is one of the most popular features of any web application. jQuery and Ajax can be used to upload images without page refresh. This article explains a simple way to implement the approach to uploading images with Codeigniter 4 Ajax Image upload using jQuery, PHP, and MySQL. This is a very simple example, you can just copy-paste and change according to your requirement.
Before started to implement the Codeigniter 4 Ajax Image upload using MySQL, look files structure:
- codeigniter-ajax-image-upload-using-mysql
- app
- Config
- App.php
- Constants.php
- Database.php
- Routes.php
- Controllers
- Gallery.php
- Models
- GalleryModel.php
- Views
- user
- index.php
- templates
- header.php
- footer.php
- menus.php
- user
- Config
- public
- .htaccess
- index.php
- .htaccess
- .env
- assets
- images
- uploads
- css
- style.css
- sticky-footer-navbar.css
- app
Step 1 – Install Codeigniter 4 Application
To handle the actual install you would use the following command in your terminal or visit Codeigniter site and download the Codeigniter application.
1 |
composer create-project codeigniter4/appstarter codeigniter-ajax-image-upload-using-mysql |
Display Errors
You may turn on the feature to errors, go to the
app/Config/Boot/production.php
and change display_errors prop value to 1 from 0.
1 |
ini_set('display_errors', '1'); |
Step 2 – Basic App Configurations
Now, you need to some basic configuration on the app/config/app.php file.
1 2 3 |
public $baseURL = 'http://localhost:8080'; To public $baseURL = 'http://localhost/codeigniter-ajax-image-upload-using-mysql'; |
Step 3: Create the Database and Table
For this tutorial, you need a MySQL database with the following table:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php CREATE TABLE `gallery` ( `id` int(11) NOT NULL COMMENT 'Primary Key', `image_name` varchar(100) NOT NULL COMMENT 'Image Name', `file_type` varchar(255) NOT NULL COMMENT 'File Type', `created_date` datetime NOT NULL DEFAULT current_timestamp() COMMENT 'Date Created' ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='user table'; ALTER TABLE `gallery` ADD PRIMARY KEY (`id`); ALTER TABLE `gallery` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Primary Key'; COMMIT; ?> |
Step 4: Setup and Configure Database access
Update the file app/Config/Database.php OR .env file:
i) .env
1 2 3 4 5 |
database.default.hostname = localhost database.default.database = demo_DB database.default.username = root database.default.password = root database.default.DBDriver = MySQLi |
ii) Database.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php // configure database public $default = [ 'DSN' => '', 'hostname' => 'localhost', 'username' => '', 'password' => '', 'database' => '', 'DBDriver' => 'MySQLi', 'DBPrefix' => '', 'pConnect' => false, 'DBDebug' => (ENVIRONMENT !== 'production'), 'charset' => 'utf8', 'DBCollat' => 'utf8_general_ci', 'swapPre' => '', 'encrypt' => false, 'compress' => false, 'strictOn' => false, 'failover' => [], 'port' => 3306, ]; ?> |
Step 4: Create and Update User Model
Create a model file named UserModel.php inside “app/Models” folder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?php /** * Description of Gallery Model * * @author Team TechArise * * @email info@techarise.com */ namespace App\Models; use CodeIgniter\Model; class GalleryModel extends Model { protected $table = 'gallery'; protected $allowedFields = [ 'image_name', 'file_type', 'created_date' ]; } ?> |
Step 5: Create controllers
Create a controllers file named User.php inside “app/Controllers” folder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
<?php /** * Description of Users Controller * * @author Team TechArise * * @email info@techarise.com */ namespace App\Controllers; use App\Models\GalleryModel; class Gallery extends BaseController { public function index() { $data = array(); helper(['form']); return view('gallery/index', $data); } public function upload() { $gallery = new GalleryModel(); helper(['form', 'url']); $database = \Config\Database::connect(); $builder = $database->table('users'); $validationRule = [ 'file_name' => [ 'rules' => 'uploaded[file_name]' . '|is_image[file_name]' . '|mime_in[file_name,image/jpg,image/jpeg,image/gif,image/png]' . '|max_size[file_name,4096]', ], ]; $response = [ 'success' => false, 'data' => $validationRule, 'msg' => "Image could not upload" ]; if ($this->validate($validationRule)) { $imageFile = $this->request->getFile('file_name'); // set image path $imageFile->move(ROOT_UPLOAD_PATH); $data = [ 'image_name' => $imageFile->getClientName(), 'file_type' => $imageFile->getClientMimeType() ]; $save = $gallery->save($data); $response = [ 'success' => true, 'data' => $save, 'msg' => "Image successfully uploaded" ]; } return $this->response->setJSON($response); } } ?> |
Add/Update code the file app/Config/Routes.php in your CodeIgniter installation with you controller’s name.
1 2 3 4 |
<?php // custom create routes $routes->get('/', 'Gallery::index'); ?> |
Step 6: Create views
Create a views file named index.php inside “add/Views/gallery” folder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?php echo view('templates/header'); ?> <main class="flex-shrink-0"> <div class="container mt-5"> <div class="row justify-content-md-center"> <div class="col-7"> <h2 class="mt-5 text-center">Codeigniter 4 Ajax Image upload using MySQL</h2> <form method="post" id="upload-image-form" class="upl-img" enctype="multipart/form-data"> <div id="alertMessage" class="alert alert-warning mb-3" style="display: none"> <span id="alertMsg"></span> </div> <div class="text-center"> <img class="mb-3" id="ajaxImgUpload" alt="Preview Image" src="https://via.placeholder.com/300.png?text=TECHARISE.COM" /> </div> <div class="form-group mb-3"> <input type="file" name="file_name" multiple="true" id="file-name" onchange="onFileUpload(this);" class="form-control form-control-lg" accept="image/*"> </div> <div class="d-grid"> <button type="submit" class="btn btn-sm btn-primary">Upload</button> </div> </form> </div> </div> </div> </main> <?php echo view('templates/footer'); ?> |
Step 7: Create ajax
Now in app.js, we will handle functionality to upload image Ajax request, inside “assets/js” folder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
function onFileUpload(input, id) { id = id || '#ajaxImgUpload'; if (input.files && input.files[0]) { var reader = new FileReader(); reader.onload = function(e) { $(id).attr('src', e.target.result).width(300) }; reader.readAsDataURL(input.files[0]); } } jQuery(document).ready(function() { jQuery('#upload-image-form').on('submit', function(e) { jQuery('.uploadBtn').html('Uploading ...'); jQuery('.uploadBtn').prop('Disabled'); e.preventDefault(); if (jQuery('#file-name').val() == '') { alert("Choose File"); jQuery('.uploadBtn').html('Upload'); jQuery('.uploadBtn').prop('enabled'); document.getElementById("upload-image-form").reset(); } else { jQuery.ajax({ url: base_url + "/gallery/upload", method: "POST", data: new FormData(this), processData: false, contentType: false, cache: false, dataType: "json", success: function(res) { console.log(res.success); if (res.success == true) { jQuery('#ajaxImgUpload').attr('src', 'https://via.placeholder.com/300.png?text=TECHARISE.COM'); jQuery('#alertMsg').html(res.msg); jQuery('#alertMessage').show(); } else if (res.success == false) { jQuery('#alertMsg').html(res.msg); jQuery('#alertMessage').show(); } setTimeout(function() { jQuery('#alertMsg').html(''); jQuery('#alertMessage').hide(); }, 4000); jQuery('.uploadBtn').html('Upload'); jQuery('.uploadBtn').prop('Enabled'); document.getElementById("upload-image-form").reset(); } }); } }); }); |
Create files named (header.php, menus.php and footer.php)
This file contains the header and footer section of the webpage. The Bootstrap library is used to provide a better UI, so, include it in the header and footer section.
i) header.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!doctype html> <html lang="en"> <head> <link rel="canonical" href="https://techarise.com/" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="icon" type="image/ico" href="https://techarise.com/wp-content/themes/v1/favicon.ico"> <!-- Bootstrap CSS --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <!--- Custom css ---> <link href="<?php print HTTP_CSS_PATH; ?>sticky-footer-navbar.css" rel="stylesheet"> <link href="<?php print HTTP_CSS_PATH; ?>style.css" rel="stylesheet"> <title>Codeigniter 4 Ajax Image upload using MySQL | Tech Arise</title> </head> <body> <?php echo view('templates/menus'); ?> |
ii) menus.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<header> <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark"> <div class="container-fluid"> <a class="navbar-brand" href="https://techarise.com">TechArise</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarCollapse"> <ul class="navbar-nav me-auto mb-2 mb-md-0"> <li class="nav-item"> <a class="nav-link active" aria-current="page" href="https://techarise.com">Home</a> </li> </ul> </div> </div> </nav> </header> |
iii) footer.php
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<footer class="footer"> <div class="container"> </div> </footer> <script> var base_url = "<?php echo base_url(); ?>" </script> <script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script> <script src="<?php print HTTP_JS_PATH;?>app.js"></script> </body> </html> |