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
.env
file 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
.env
file. - Remove # from the start of the
security.tokenName
,security.headerName
,security.cookieName
,security.expires
,andsecurity.regenerate
. - I update the
security.tokenName
value 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.php
file. - 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
images
using 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_table
and 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 deleteimages
table 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
Images
Model –
php spark make:model Images
- Open
app/Models/Images.php
file. - In
$allowedFields
Array 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.php
file. - 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
PagesController
Controller –
php spark make:controller PagesController
- Open
app/Controllers/PagesController.php
file. - Import
Files
Model. - Create 2 methods –
- index() – Fetch all records from
files
table and assign to$data['files']
. Loadindex
view 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:8080
in 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.