How to Upload File in CakePHP 4, Part-5

Handling File Uploads in CakePHP 4 File upload in CakePHP 3
CakePHP 4 Moving the uploaded file from the its temporary location to the desire target location to using CakePHP 4 library to upload files. We need to use PHP’s  moveTo method upload file  to the server. In this tutorial you will learn how to upload a file in CakePHP.


Create Database Table

Store the uploaded file information, create a table (Posts) in to Database (blog_database)
-- Database: `blog_database`

-- Table structure for table `posts`

CREATE TABLE `posts` (
`id` int(100) NOT NULL,
`title` varchar(100) NOT NULL,
`description` varchar(100) NOT NULL,
`post_image` varchar(100) NOT NULL,
`created` datetime NOT NULL,
`updated` datetime NOT NULL

File Upload Directory

Create the directory (webroot/img/post_image) where you want to upload or store images the upload directory using $targetPath
$targetPath = WWW_ROOT. 'img'. DS . 'post_image'. DS.;



In this post we will use the src/controller/PostsController.php  controller to create a add function to upload file in database.

// src/Controller/PostsController.php

namespace AppController;
use AppControllerAppController;
use CakeEventEventInterface;
use CakeDatasourceFactoryLocator;

class PostsController extends AppController{

public $postsTableObj;

public function beforefilter(EventInterface $event){
    $this->postsTableObj = FactoryLocator::get('Table')->get('Posts');

public function add(){
$postEnt = $this->postsTableObj->newEmptyEntity();
if ($this->request->is('post')) {
    $postData = $this->request->getData();
$postImage = $this->request->getData('post_image');
$name = $postImage->getClientFilename();
$type = $postImage->getClientMediaType();
$targetPath = WWW_ROOT. 'img'. DS . 'post_image'. DS. $name;
if ($type == 'image/jpeg' || $type == 'image/jpg' || $type == 'image/png') {
if (!empty($name)) {
if ($postImage->getSize() > 0 && $postImage->getError() == 0) {
$postData['post_image'] = $name;
    $posts = $this->postsTableObj->patchEntity($postEnt, $postData);
if ($this->postsTableObj->save($posts)) {
    $this->Flash->success(__('Your post has been saved.'));
return $this->redirect(['controller'=>'Posts','action' => 'index']);
    $this->Flash->error(__('Unable to add your post.'));
return $this->redirect(['controller'=>'Posts','action' => 'add']);
$this->set(compact('postEnt', $postEnt));


In Model src/Model/Table/PostsTable.php  to validate form and insert date time value in created and updated using addBehavior function with Timestamp.

namespace AppModelTable;
use CakeORMTable;
use CakeValidationValidator;

class PostsTable extends Table
public function initialize(array $config): void
$this->addBehavior('Timestamp', [
'events' => [
'Model.beforeSave' => [
'created' => 'new',
'updated' => 'always'

public function validationDefault(Validator $validator): Validator

return $validator;



Templates/Posts/add.php view is responsible for creating the upload form and display the uploaded file list.
<div class="text-center" style="margin-top: 50px;">
<h4>Add Post</h4>
<div class="container">
<div class="row">
<div class="col-sm-3"></div>
<div class="col-sm-6">
<?php echo $this->Form->create($postEnt, ['name'=>'add_post', 'class'=>'was-validated',
'enctype'=>'multipart/form-data']) ?>
<div class="form-group">
<?php echo $this->Form->control('title', ['type'=>'text', 'class'=>'form-control','placeholder'=>'Enter title','required'=>true]);?>
<div class="form-group">
<?php echo $this->Form->control('description', ['type'=>'text', 'class'=>'form-control','placeholder'=>'Enter description','required'=>true]);?>
<div class="form-group">
<?= $this->Form->control('post_image', ['type'=>'file', 'class'=>'form-control','required'=>true]); ?>
<button type="submit" class="btn btn-success" style="float: right;">Save</button>
<?php echo $this->Form->end() ?>
You can always support by sharing on social media or recommending my blog to your friends and colleagues.   
If you have any suggestions / problems about this tutorial, please comment on the  form below.😊

Leave a Reply

Your email address will not be published.