How to upload an Image file and Display preview in CodeIgniter 4

How to upload an image file and display preview in CodeIgniter 4

 

With file uploading, the user can import data and upload media files to the server.

In this tutorial, I show how you can upload an image and other files with validation and display a preview after upload in CodeIgniter 4.

I have enabled CSRF token in the CodeIgniter project.


 1. Enable CSRF

  • Open .env file.
  • Remove # from the start of the app.CSRFProtection, app.CSRFTokenNameapp.CSRFCookieNameapp.CSRFExpire, and app.CSRFRegenerate.
  • I update the app.CSRFTokenName value with 'csrf_hash_name'. With this name read CSRF hash. You can update it with any other value.
app.CSRFProtection = true
app.CSRFTokenName = 'csrf_hash_name'
app.CSRFCookieName = 'csrf_cookie_name'
app.CSRFExpire = 7200
app.CSRFRegenerate = true
# app.CSRFExcludeURIs = []
  • Open app/Config/Filters.php file.
  • Uncomment in 'csrf' in 'before' if commented.
// Always applied before every request
public $globals = [
    'before' => [
       //'honeypot'
       'csrf',
    ],
    'after' => [
       'toolbar',
       //'honeypot'
    ],
];

2. Route

  • Open app/Config/Routes.php file.
  • Define 2 routes –
    • / – Display file upload view.
    • users/fileUpload – It is used to upload a file.

Completed Code

$routes->get('/', 'UsersController::index');
$routes->post('users/fileUpload', 'UsersController::fileUpload');

3. Controller

  • Create UsersController.php file in app/Controllers/ folder.
  • Open the file.
  • Create 2 methods –
    • index() – Load users view.
    • fileUpload() – This method is called on form submit to upload the file.

Set file validation –

'file' => 'uploaded[file]|max_size[file,1024]|ext_in[file,jpg,jpeg,docx,pdf],'
    1. uploaded – Fails if the name of the parameter does not match the name of any uploaded files.
    2. max_size – Set maximum file upload size in kb.
    3. ext_in – Valid file extensions – jpg, jpeg, docx, pdf.

Here, the 1st parameter is the name of the input field. In the example, it is ‘file’.

For example, If the input field name is ‘imagefile’ then validation is like this – 'uploaded[imagefile]|max_size[imagefile,1024]|ext_in[imagefile,jpg,jpeg],'.

NOTE – You can learn more file validation from here.

If the file is not validated then return to the users view with validation response.

If the file is validated then get the file name and extension. I used $file->getRandomName() to generate a random name but you can create any other meaningful name and assign it to $newName.

I am storing files in the public/uploads folder using move() method. 1st parameter is the file upload path and 2nd parameter is the name.

Assign file path to $filepath variable for preview. Using SESSION flash to display "Uploaded Successfully!" message and file preview.

Redirect to "/" route.

Completed Code

<?php namespace App\Controllers;

class UsersController extends BaseController
{

   public function index(){
     return view('users');
   }

   public function fileUpload(){

     // Validation
     $input = $this->validate([
        'file' => 'uploaded[file]|max_size[file,1024]|ext_in[file,jpg,jpeg,docx,pdf],'
     ]);

     if (!$input) { // Not valid
         $data['validation'] = $this->validator; 
         return view('users',$data); 
     }else{ // Valid

         if($file = $this->request->getFile('file')) {
            if ($file->isValid() && ! $file->hasMoved()) {
               // Get file name and extension
               $name = $file->getName();
               $ext = $file->getClientExtension();

               // Get random file name
               $newName = $file->getRandomName(); 

               // Store file in public/uploads/ folder
               $file->move('../public/uploads', $newName);

               // File path to display preview
               $filepath = base_url()."/uploads/".$newName;
               
               // Set Session
               session()->setFlashdata('message', 'Uploaded Successfully!');
               session()->setFlashdata('alert-class', 'alert-success');
               session()->setFlashdata('filepath', $filepath);
               session()->setFlashdata('extension', $ext);

            }else{
               // Set Session
               session()->setFlashdata('message', 'File not uploaded.');
               session()->setFlashdata('alert-class', 'alert-danger');

            }
         }

     }
  
     return redirect()->route('/'); 
   }

}

4. View

Create users.php file in app/Views/.

Display bootstrap alert message if 'message' SESSION exists. Also, set alert class using 'alert-class' Session.

Display file preview if 'filepath' SESSION exists. Check file extension. If the extension is equals to ‘jpg’ or ‘jpeg’ then pass session()->getFlashdata('filepath') to img src attribute otherwise create anchor element and pass session()->getFlashdata('filepath') to href attribute.

Load validation service \Config\Services::validation() and assign it to $validation.

Create <form method="post" action="<?=site_url('users/fileUpload')?>" enctype="multipart/form-data">.

Create a file element and submit button. Display error in <div > if not validated.

Completed Code

<!doctype html>
<html>
<head>
   <title>How to upload an image file and display preview in CodeIgniter 4</title>
   <link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>

  <div class="container">

    <div class="row">
      <div class="col-md-12">
        <?php 
        // Display Response
        if(session()->has('message')){
        ?>
        <div class="alert <?= session()->getFlashdata('alert-class') ?>">
           <?= session()->getFlashdata('message') ?>
        </div>
        <?php
        }
        ?>

        <?php 
        // File preview
        if(session()->has('filepath')){ ?>

           <?php 
           if(session()->getFlashdata('extension') == 'jpg' || session()->getFlashdata('extension') == 'jpeg'){
           ?>
              <img src="<?= session()->getFlashdata('filepath') ?>" with="200px" height="200px"><br>

           <?php
           }else{
           ?>
              <a href="<?= session()->getFlashdata('filepath') ?>">Click Here..</a>
           <?php
           }
        }
        ?>

        <?php $validation = \Config\Services::validation(); ?>

        <form method="post" action="<?=site_url('users/fileUpload')?>" enctype="multipart/form-data">

           <?= csrf_field(); ?>
           <div class="form-group">
              <label for="file">File:</label>

              <input type="file" class="form-control" id="file" name="file" />
              <!-- Error -->
              <?php if( $validation->getError('file') ) {?>
                 <div class='alert alert-danger mt-2'>
                    <?= $validation->getError('file'); ?>
                 </div>
              <?php }?>

           </div>

           <input type="submit" class="btn btn-success" name="submit" value="Upload">
        </form>
      </div>
    </div>
  </div>

</body>
</html>

5. Output

View Output


6. Conclusion

If in your project CSRF token is disabled then remove csrf_field() from view.

Before setting max_size for validation make sure to check post_max_size and upload_max_filesize in php.ini file and update it accordingly if required.



Comments