When you are allowing users to upload files then it is hard to manage when they are huge in numbers.
To resolve it you can store them in a database that makes the retrieving, updating, and deletion process easier.
In this tutorial, I show how you can upload and store file to MySQL database in the CodeIgniter 4 project.

Contents
1. Database configuration
- Open
.envfile which is available at the project root.
NOTE – If dot (.) not added at the start then rename the file to .env.
- Remove # from start of
database.default.hostname,database.default.database,database.default.username,database.default.password, anddatabase.default.DBDriver. - Update the configuration and save it.
database.default.hostname = 127.0.0.1 database.default.database = testdb database.default.username = root database.default.password = database.default.DBDriver = MySQLi
2. Enable CSRF
- Again open
.envfile. - Remove # from the start of the
security.tokenName,security.headerName,security.cookieName,security.expires,andsecurity.regenerate. - I update the
security.tokenNamevalue with'csrf_hash_name'. With this name read CSRF hash. You can update it with any other value. - If you don’t want to regenerate CSRF hash after each request then set
security.regenerate = false.
security.tokenName = 'csrf_hash_name' security.headerName = 'X-CSRF-TOKEN' security.cookieName = 'csrf_cookie_name' security.expires = 7200 security.regenerate = true
- Open
app/Config/Filters.phpfile. - Uncomment
'csrf'in'before'if commented.
// Always applied before every request
public $globals = [
'before' => [
//'honeypot'
'csrf',
],
'after' => [
'toolbar',
//'honeypot'
],
];
3. Create Table
- Create a new table
imagesusing migration.
php spark migrate:create create_images_table
- Now, navigate to
app/Database/Migrations/folder from the project root. - Find a PHP file that ends with
create_images_tableand open it. - Define the table structure in the
up()method.- filename – This field is used to store file name.
- path – This field is used to store the upload file path.
- Using the
down()method deleteimagestable which calls when undoing migration.
<?php namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class CreateImagesTable extends Migration
{
public function up() {
$this->forge->addField([
'id' => [
'type' => 'INT',
'constraint' => 10,
'unsigned' => true,
'auto_increment' => true,
],
'filename' => [
'type' => 'VARCHAR',
'constraint' => '100',
],
'path' => [
'type' => 'VARCHAR',
'constraint' => '255',
],
]);
$this->forge->addKey('id', true);
$this->forge->createTable('images');
}
//--------------------------------------------------------------------
public function down() {
$this->forge->dropTable('images');
}
}
- Run the migration –
php spark migrate
4. Model
- Create
ImagesModel –
php spark make:model Images
- Open
app/Models/Images.phpfile. - In
$allowedFieldsArray specify field names –['filename','path']that can be set during insert and update.
Completed Code
<?php
namespace App\Models;
use CodeIgniter\Model;
class Images extends Model
{
protected $DBGroup = 'default';
protected $table = 'images';
protected $primaryKey = 'id';
protected $useAutoIncrement = true;
protected $insertID = 0;
protected $returnType = 'array';
protected $useSoftDeletes = false;
protected $protectFields = true;
protected $allowedFields = ['filename','path'];
// Dates
protected $useTimestamps = false;
protected $dateFormat = 'datetime';
protected $createdField = 'created_at';
protected $updatedField = 'updated_at';
protected $deletedField = 'deleted_at';
// Validation
protected $validationRules = [];
protected $validationMessages = [];
protected $skipValidation = false;
protected $cleanValidationRules = true;
// Callbacks
protected $allowCallbacks = true;
protected $beforeInsert = [];
protected $afterInsert = [];
protected $beforeUpdate = [];
protected $afterUpdate = [];
protected $beforeFind = [];
protected $afterFind = [];
protected $beforeDelete = [];
protected $afterDelete = [];
}
5. Route
- Open
app/Config/Routes.phpfile. - Define 2 routes –
- / – Load files from database and display file upload view.
- page/fileUpload – To upload a file.
Completed Code
$routes->get('/', 'PagesController::index');
$routes->post('page/fileUpload', 'PageController::fileUpload');
6. Controller
- Create
PagesControllerController –
php spark make:controller PagesController
- Open
app/Controllers/PagesController.phpfile. - Import
FilesModel. - Create 2 methods –
- index() – Fetch all records from
filestable and assign to$data['files']. Loadindexview and pass$data. - fileUpload() – Using this method upload file and its calls on
<form >submit.
- index() – Fetch all records from
Validate the file. If file is not validated then return to index view and pass error response.
If file is validated successfully then read file name and extension and assign to the variables. Upload the file to public/uploads folder and assign file path to $filepath variable.
Insert a record to files table where pass $insertdata Array. Specify $name to $insertdata['filename'] and $filepath to $insertdata['path'].
Store the success message in session()->setFlashdata('message') and class name in session()->setFlashdata('alert-class') and redirect to route("/").
Completed Code
<?php
namespace App\Controllers;
use App\Models\Files;
class PageController extends BaseController{
public function index(){
// Fetch data
$files = new Files();
$data['files'] = $files->findAll();
return view('index',$data);
}
// Upload file
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('index',$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', $name);
// File path to display preview
$filepath = base_url()."/uploads/".$name;
// Insert Record
$files = new Files();
$insertdata['filename'] = $name;
$insertdata['path'] = $filepath;
$files->insert($insertdata);
// Set Session
session()->setFlashdata('message', 'Uploaded Successfully!');
session()->setFlashdata('alert-class', 'alert-success');
}else{
// Set Session
session()->setFlashdata('message', 'File not uploaded.');
session()->setFlashdata('alert-class', 'alert-danger');
}
}
}
return redirect()->route('/');
}
}
7. View
Create index.php file in app/Views/.
Display bootstrap alert message if SESSION message variable is set.
Loop on $files Array to display file. If file is an image then display preview using <img > tag where pass $path in src attribute. If it is not an image file then display link using <a > tag where pass $path in href attribute.
Create <form method="post" action="<?=site_url('page/fileUpload')?>" enctype="multipart/form-data"> to upload file.
Completed Code
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>How to Upload and store file to MySQL database 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 mt-5">
<div class="col-md-12">
<?php
// Display Response
if(session()->has('message')){
?>
<div class="alert <?= session()->getFlashdata('alert-class') ?>">
<?= session()->getFlashdata('message') ?>
</div>
<?php
}
?>
<div class='row'>
<?php
// Display existing files
$imageext_arr = array("png","jpg","jpeg");
foreach($files as $file){
$filename = $file['filename'];
$path = $file['path'];
$ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
$isImage = false;
if(in_array($ext,$imageext_arr)){
$isImage = true;
}
?>
<div class="col-md-3">
<?php
if($isImage){
echo "<img src='".$path."' width='200px'>";
}else{
echo "<a href='".$path."' target='_blank'>".$filename."</a>";
}
?>
</div>
<?php
}
?>
</div>
<?php $validation = \Config\Services::validation(); ?>
<form method="post" action="<?=site_url('page/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>
8. Run
- Navigate to the project using Command Prompt if you are on Windows or terminal if you are on Mac or Linux, and
- Execute “php spark serve” command.
php spark serve
- Run
http://localhost:8080in the web browser.
9. Output
10. Conclusion
For managing uploaded files in more better way you can store them in MySQL database using above script.
To store data userwise create a new field to store userid.
If you found this tutorial helpful then don't forget to share.