Multiple File Upload in CodeIgniter 4 Step-by-step Easy Tutorial

Multiple File Upload In CodeIgniter 4 Step-by-step Easy Tutorial

Avatar photoPosted by

Today I will teach you to make a multiple file upload in CodeIgniter 4. Uploading files are common on most of the online platforms today, like uploading photos on social media, uploading videos in a video sharing platform or uploading resume in a job searching site.

We will be using CodeIgniter 4 on this tutorial. CodeIgniter is one of the most powerful PHP frameworks. It is an open-source web framework that is used for rapid web development. It is popular for its exceptional performance, small footprint, requires nearly zero configuration, thorough documentation and many more.

Step 1: Install CodeIgniter 4

For us to install CodeIgniter 4 we can install via composer or directly download CodeIgniter 4 here:

Install via composer:

composer create-project codeigniter4/appstarter ci-4-multiple-file-upload

Step 2: Change CodeIgniter Environment

The default environment of CodeIgniter is production, it is a safety feature to add security in case settings are messed up when it goes live. For us to change the environment we will rename or copy the file env to .env. Once it is renamed, open the file and uncomment and change the CI_ENVIRONMENT value from production to development.

.env

CI_ENVIRONMENT = development

Step 3: Configure Database

After setting up the environment, we will then configure our database. You can configure it on .env or on the config file located at app/Config/Database.php. For this tutorial we will configure it on app/Config/Database.php.

Configure the database connection values:

app/Config/Database.php

<?php
 
namespace Config;
 
use CodeIgniter\Database\Config;
 
/**
 * Database Configuration
 */
class Database extends Config
{
    /**
     * The directory that holds the Migrations
     * and Seeds directories.
     *
     * @var string
     */
    public $filesPath = APPPATH . 'Database' . DIRECTORY_SEPARATOR;
 
    /**
     * Lets you choose which connection group to
     * use if no other is specified.
     *
     * @var string
     */
    public $defaultGroup = 'default';
 
    /**
     * The default database connection.
     *
     * @var array
     */
    public $default = [
        'DSN'      => '',
        'hostname' => 'localhost',
        'username' => 'root',
        'password' => '',
        'database' => 'ci_4_fileupload',
        'DBDriver' => 'MySQLi',
        'DBPrefix' => '',
        'pConnect' => false,
        'DBDebug'  => (ENVIRONMENT !== 'production'),
        'charset'  => 'utf8',
        'DBCollat' => 'utf8_general_ci',
        'swapPre'  => '',
        'encrypt'  => false,
        'compress' => false,
        'strictOn' => false,
        'failover' => [],
        'port'     => 3306,
    ];
 
    /**
     * This database connection is used when
     * running PHPUnit database tests.
     *
     * @var array
     */
    public $tests = [
        'DSN'      => '',
        'hostname' => '127.0.0.1',
        'username' => '',
        'password' => '',
        'database' => ':memory:',
        'DBDriver' => 'SQLite3',
        'DBPrefix' => 'db_',  // Needed to ensure we're working correctly with prefixes live. DO NOT REMOVE FOR CI DEVS
        'pConnect' => false,
        'DBDebug'  => (ENVIRONMENT !== 'production'),
        'charset'  => 'utf8',
        'DBCollat' => 'utf8_general_ci',
        'swapPre'  => '',
        'encrypt'  => false,
        'compress' => false,
        'strictOn' => false,
        'failover' => [],
        'port'     => 3306,
    ];
 
    //--------------------------------------------------------------------
 
    public function __construct()
    {
        parent::__construct();
 
        // Ensure that we always set the database group to 'tests' if
        // we are currently running an automated test suite, so that
        // we don't overwrite live data on accident.
        if (ENVIRONMENT === 'testing')
        {
            $this->defaultGroup = 'tests';
        }
    }
 
    //--------------------------------------------------------------------
 
}

Step 4: Create A Model and Migration

Model – it a class that represents a database table.

Migration – like version control for the database that allows us to modify and share database schema to your team.

Execute this command on the Terminal or CMD to create a model:

php spark make:model FileUploadModel

open the created model at app/Models/FileUploadModel.php. Inside the file you can see configuration options, you can read the documentation to further learn about its configuration options. We will now update the configs:

app/Models/FileUploadModel.php

<?php

namespace App\Models;

use CodeIgniter\Model;

class FileUploadModel extends Model
{
	protected $DBGroup              = 'default';
	protected $table                = 'fileuploads';
	protected $primaryKey           = 'id';
	protected $useAutoIncrement     = true;
	protected $insertID             = 0;
	protected $returnType           = 'object';
	protected $useSoftDeletes       = false;
	protected $protectFields        = true;
	protected $allowedFields        = ['filename', 'filepath', 'type'];

	// Dates
	protected $useTimestamps        = true;
	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          = [];
}

After creating the model, we will then create a migration file. Execute this command on the Terminal or CMD to create a migration:

php spark make:migration AddFileUpload

Open the created migration file on app/Database/Migrations/ and paste these codes:

<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class AddFileUpload extends Migration
{
	public function up()
	{
		$this->forge->addField([
            'id' => [
                'type' => 'BIGINT',
                'constraint' => 255,
                'unsigned' => true,
                'auto_increment' => true
            ],
            'filename' => [
                'type' => 'VARCHAR',
                'constraint' => '255',
            ],
            'filepath' => [
                'type' => 'VARCHAR',
                'constraint' => '255',
            ],
			'type' => [
                'type' => 'VARCHAR',
                'constraint' => '255',
            ],
            'created_at' => [
                'type' => 'TIMESTAMP',
                'null' => true
            ],
            'updated_at' => [
                'type' => 'TIMESTAMP',
                'null' => true
            ],
        ]);

		$this->forge->addPrimaryKey('id');
        $this->forge->createTable('fileuploads');
	}

	public function down()
	{
		$this->forge->dropTable('fileuploads');
	}
}

Run the migration by executing the migrate command:

php spark migrate

Step 5: Create A Controller

Execute this command to create a controller:

php spark make:controller FileUpload

After executing the command, it will create file located at app/Controllers. Open those file and insert these codes:

<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use App\Models\FileUploadModel;

class FileUpload extends BaseController
{

	public function index()
	{
		$fileUploadModel = new FileUploadModel();
		return view('file-upload', ['fileUploads' => $fileUploadModel->orderBy('created_at', 'asc')->findAll()]);
	}

	public function multipleUpload() 
	{
		$filesUploaded = 0;

		if($this->request->getFileMultiple('fileuploads'))
		{
			$files = $this->request->getFileMultiple('fileuploads');

			foreach ($files as $file) {

				if ($file->isValid() && ! $file->hasMoved())
				{
					$newName = $file->getRandomName();
					$file->move(WRITEPATH.'uploads', $newName);
					$data = [
						'filename' => $file->getClientName(),
						'filepath' => 'uploads/' . $newName,
						'type' => $file->getClientExtension()
					];
					$fileUploadModel = new FileUploadModel();
					$fileUploadModel->save($data);
					$filesUploaded++;
				}
				
			}

		}

		if($filesUploaded <= 0) {
			return redirect()->back()->with('error', 'Choose files to upload.');
		}

		return redirect()->back()->with('success', $filesUploaded . ' File/s uploaded successfully.');

	}
}

Step 6: Register Routes

After creating a controller, register these 2 routes.

app/Config/Routes.php

$routes->get('/file-upload', 'FileUpload::index');
$routes->post('/multiple-file-upload', 'FileUpload::multipleUpload');

Step 7: Create View File

View files are web page or fragments of a page like header or footer and etc. Views can be embedded to other views whenever you need hierarchy on view files.

Create this view file “app/Views/file-upload.php” and insert these codes:

app/Views/file-upload.php

<!DOCTYPE html>
<html>
<head>
    <title>Multitple File Upload</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</head>
<body>
   
   
<div class="container">
    <h2 class="text-center mt-5 mb-3">Multitple File Upload</h2>
    <div class="card">
        <div class="card-body">
            <?php if (session()->getFlashdata('success')) : ?>
                <div class="alert alert-success">
                    <b><?php echo session()->getFlashdata('success') ?></b>
                </div>
            <?php endif ?>
            <?php if (session()->getFlashdata('error')) : ?>
                <div class="alert alert-danger">
                    <b><?php echo session()->getFlashdata('error') ?></b>
                </div>
            <?php endif ?>
 
            <form class="row" method="post" action="<?php echo base_url('/multiple-file-upload'); ?>" enctype="multipart/form-data">
                <div class="col-auto">
                    <input type="file" name="fileuploads[]" class=" form-control" multiple >
                </div>
                <div class="col-auto">
                    <button type="submit" class="btn btn-outline-primary mb-3">Upload Files</button>
                </div>
            </form>
            <table class="table table-bordered mt-3">
                <thead>
                    <tr>
                        <th>Filename</th>
                        <th>Filepath</th>
                        <th>File Type</th>
                    </tr>
                </thead>
                <tbody>
                <?php foreach ($fileUploads as $fileUpload):?>
                    <tr>
                        <td><?= $fileUpload->filename ?></td>
                        <td><?= $fileUpload->filepath ?></td>
                        <td><?= $fileUpload->type ?></td>
                    </tr>
                    <?php endforeach;?>
                </tbody>
                     
            </table>
        </div>
    </div>
 
</div>
   
   
</body>
</html>

Step 8 : Run the Application

Now that we have completed the steps above we will now run the app. To run the app, execute this command:

php spark serve

After successfully running your app, open this URL in your browser:

http://localhost:8080/file-upload

Screenshots:

Multiple File Upload in CodeIgniter 4

laravel 8 multiple file upload index page Binaryboxtuts