Uploading Files With Cake Php and Fileupload Plugin

Uploading Files With Cake Php and Fileupload Plugin
Photo by Robert Reyes / Unsplash

I just release new version of my FileUpload plugin for CakePHP.

It will make uploading and downloading files really easi. Want to see? Continue reading.


If you have existing application you can skip right to Create fileupload app.

  • CakePHP 4
  • Https server
  • PHP 7.x or 8
  • php extensions mgstring, intl, SimpleXML, PDO

For more informations check CakePHP Installation


  • Docker
  • Docker-compose

Right, only those two. I will show you ho to do it in this tutorial.

Prepare Environment

I will use for this tutorial my CakePHP starter kit, but you are ok to use your existing installation. This starter kit contains all you will need to create your app in no time. It contains:

  • CakePHP 4
  • PHP 7.4.16, witth all required extensions
  • Postgres
  • Minio (s3 storage)
  • Redis
  • Adminer

Ok so start it up, and run comands in shell as follows

mkdir fileupload-tutorial
cd fileupload-tutorial
docker run --rm --volume $(pwd):/app ghcr.io/maymeow/php-ci-cd/php-ci-cd:7.4.16-cs-1 sh -c "composer create-project --prefer-dist maymeow/cakephp-starter-kit:dev-main /app"
sudo chown -R $USER:$GID .

You can run ls -la to check if all folders are owned by you. Ok now we create our application

Create fileupload app

Installing plugin

First of all we need to install fileupload plugin and load it, run following command

docker-compose -f docker-compose.dev.yml run --rm cake-app composer require maymeow/file-upload

and load it

docker-compose -f docker-compose.dev.yml run --rm cake-app php bin/cake.php plugin load FileUpload

Creating MVC for Files

Next step is to create MVC for our files controller. For our need is enough to have table with file name and time for creating and modifiing. Create migration as follow

docker-compose -f docker-compose.dev.yml run --rm cake-app php bin/cake.php bake migration CreateFiles name:string created modified

push changes to database

docker-compose -f docker-compose.dev.yml run --rm cake-app php bin/cake.php migrations migrate

and create MVC for our files

docker-compose -f docker-compose.dev.yml run --rm cake-app php bin/cake.php bake all Files

Now is time to start our application with following command

docker-compose -f docker-compose.dev.yml up -d

Navigate to the on your favorite browser an you will see Welcome to CakePHP 4.2.10 Strawberry message. This is OK and or applications is now running. To open or files contriller go to

Creating upload view and controller

Standardly CakePHP create controller for viewing, list, editing and adding. But it is not what we need. We want upload file to the server and this one is missing. So create it. First of all create new Modelless form

docker-compose -f docker-compose.dev.yml run --rm cake-app php bin/cake.php bake form Upload 

Navigate to src/Form/UploadForm.php and edit _buildSchema as follows

protected function _buildSchema(Schema $schema): Schema
    return $schema->addField('file', 'string');

Creating view and controller for Upload form

Go to src/Controller/FilesController and add following function

public function upload()
    $uploadForm = new UploadForm();


and create upload.php view in templates/Files with following content

 * @var \App\View\AppView $this
 * @var \App\Form\UploadForm $uploadForm
<div class="row">
    <aside class="column">
        <div class="side-nav">
            <h4 class="heading"><?= __('Actions') ?></h4>
            <?= $this->Html->link(__('List Files'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
    <div class="column-responsive column-80">
        <div class="files form content">
            <?= $this->Form->create($uploadForm, ['type' => 'file']) ?>
                <legend><?= __('Upload file') ?></legend>
                echo $this->Form->control('file',  ['type' => 'file']);
            <?= $this->Form->button(__('Submit')) ?>
            <?= $this->Form->end() ?>

Now you can navigate to and if you see no error but Upload file form you are good to go.

Configuring upload plugin and uploading files

Next stem is load our components to the controller

public function initialize(): void
    parent::initialize(); // TODO: Change the autogenerated stub

    $this->loadComponent('FileUpload.Upload', [
        'fieldName' => 'file',


Uploading files

Now you have loaded Uploadfile plugin's components so there is left some more thing to do. Update upload function as follows

public function upload()
    $uploadForm = new UploadForm();

    if ($this->request->is('post')) {
        $uploadedFile = $this->Upload->getFile($this->request);

        $file = $this->Files->newEmptyEntity();
        $file->name = $uploadedFile->getFileName();

        return $this->redirect(['action' => 'index']);


If everything goes right you will see your uploading file name in list of all files.

Downloading files

Create new function for downloading files in FilesController

public function download($fileName)
    $downloadedFile = $this->Download->getFile($fileName);

    $response = $this->response;
    $response = $response->withStringBody($downloadedFile->getFileContent());
    $response = $response->withType($downloadedFile->getFileType());

    if ($this->request->getParam('?.download') == true) {
        $response = $response->withDownload($fileName);

    return $response;

And edit templates/Files/index.ctp

# edit line 
<td><?= h($file->name) ?></td>
# to this
<td><?= $this->Html->link($file->name, ['action' => 'download', $file->name, '?' => ['download' => false]]) ?></td>

Refresh page. This will display picture you have uploaded befor by clinking on file name. If you want to show download form instead, cahnge download to true.

S3 Support

If you want to use S3 instead of local storage, you need make some small changes for it... First of all open your app_local.php and add at the end of file following config

'S3' => [
    'version' => 'latest',
    'region'  => 'us-east-1',
    'endpoint' => 'http://cake_minio:9000',
    'use_path_style_endpoint' => true,
    'credentials' => [
        'key'    => 'minioadmin',
        'secret' => 'minioadmin',

Now navigate to the and login with default creadentials, both password and username are minioadmin. In right menu go to buckets and create bucket for your needs. For this purposes i create bucket with name fileupload.tutorial.

You can check it in Object browser on sidebar.

Now let's configure our application. Update FilesController as follows:

public function initialize(): void
    parent::initialize(); // TODO: Change the autogenerated stub

    $this->loadComponent('FileUpload.Upload', [
        'fieldName' => 'file',
        'storagePath' => 'fileupload.tutorial', // bucket name
        'storage_type' => 's3'

    $this->loadComponent('FileUpload.Download', [
        'storagePath' => 'fileupload.tutorial', // bucket name
        'storage_type' => 's3'

Ok, That all now you have application which can upload / download files to local or S3 storage. Easy no?


I'm lazy person so I wanted to make it more easier (dont telling that CakePHP on itself is not easy to start) to start my applications. And with Starter kit you are good to go in few seconds and you can focus on your application.

With Fileupload plugin you can upload/download files on bot local and s3 storage literally with one line of code (dont counting configuration). I hope it will make easier for you to manage files uploading in your application to. If you find bugs please report them on FileUpload's Issue tracker, also if you have some ideas i have opened Discussions for project where you can share your ideas.

Anyway if you like this project you can contibute to it on GitHub repository which is also participating in Hacktoberfest.

Same is for CakePHP starter kit which is on Github too.


All source codes from this tutorial are awailable here on FileUpload Tutorial Github.

Thank you for reading and have a nice day!